aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/keys.txt39
-rw-r--r--Documentation/pci.txt14
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt19
-rw-r--r--Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl50
-rw-r--r--arch/i386/kernel/acpi/boot.c2
-rw-r--r--arch/i386/pci/common.c1
-rw-r--r--arch/i386/pci/i386.c9
-rw-r--r--arch/i386/pci/mmconfig.c9
-rw-r--r--arch/i386/pci/pci.h1
-rw-r--r--arch/ia64/kernel/irq_ia64.c19
-rw-r--r--arch/ia64/sn/kernel/io_init.c9
-rw-r--r--arch/ia64/sn/kernel/irq.c142
-rw-r--r--arch/ia64/sn/pci/pci_dma.c10
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_dma.c62
-rw-r--r--arch/ia64/sn/pci/tioca_provider.c8
-rw-r--r--arch/ia64/sn/pci/tioce_provider.c65
-rw-r--r--arch/powerpc/boot/Makefile4
-rw-r--r--arch/ppc/boot/lib/Makefile2
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.c9
-rw-r--r--arch/sparc/kernel/setup.c2
-rw-r--r--arch/um/kernel/time_kern.c2
-rw-r--r--arch/x86_64/Kconfig5
-rw-r--r--arch/x86_64/pci/mmconfig.c13
-rw-r--r--arch/xtensa/boot/lib/Makefile2
-rw-r--r--drivers/char/agp/Kconfig3
-rw-r--r--drivers/net/myri10ge/myri10ge.c2
-rw-r--r--drivers/pci/Makefile6
-rw-r--r--drivers/pci/bus.c21
-rw-r--r--drivers/pci/msi-altix.c210
-rw-r--r--drivers/pci/msi-apic.c100
-rw-r--r--drivers/pci/msi.c285
-rw-r--r--drivers/pci/msi.h133
-rw-r--r--drivers/pci/pci-acpi.c16
-rw-r--r--drivers/pci/pci-sysfs.c45
-rw-r--r--drivers/pci/pci.c16
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/probe.c45
-rw-r--r--drivers/pci/quirks.c47
-rw-r--r--drivers/pci/remove.c12
-rw-r--r--drivers/pci/search.c32
-rw-r--r--drivers/pci/setup-bus.c5
-rw-r--r--drivers/pci/setup-res.c40
-rw-r--r--drivers/scsi/qla1280.c24
-rw-r--r--drivers/scsi/sata_vsc.c11
-rw-r--r--drivers/video/console/mdacon.c2
-rw-r--r--drivers/video/console/vgacon.c19
-rw-r--r--drivers/video/vga16fb.c2
-rw-r--r--fs/binfmt_elf.c1
-rw-r--r--fs/binfmt_misc.c1
-rw-r--r--fs/block_dev.c32
-rw-r--r--fs/dcache.c75
-rw-r--r--fs/exec.c1
-rw-r--r--fs/locks.c57
-rw-r--r--fs/ntfs/file.c13
-rw-r--r--fs/super.c2
-rw-r--r--include/asm-alpha/vga.h2
-rw-r--r--include/asm-arm/vga.h2
-rw-r--r--include/asm-i386/msi.h10
-rw-r--r--include/asm-i386/vga.h2
-rw-r--r--include/asm-ia64/hw_irq.h15
-rw-r--r--include/asm-ia64/machvec.h7
-rw-r--r--include/asm-ia64/machvec_sn2.h7
-rw-r--r--include/asm-ia64/msi.h12
-rw-r--r--include/asm-ia64/sn/intr.h8
-rw-r--r--include/asm-ia64/sn/pcibr_provider.h5
-rw-r--r--include/asm-ia64/sn/pcibus_provider_defs.h17
-rw-r--r--include/asm-ia64/sn/tiocp.h3
-rw-r--r--include/asm-ia64/vga.h2
-rw-r--r--include/asm-m32r/vga.h2
-rw-r--r--include/asm-mips/vga.h2
-rw-r--r--include/asm-powerpc/vga.h4
-rw-r--r--include/asm-sparc64/vga.h2
-rw-r--r--include/asm-x86_64/msi.h10
-rw-r--r--include/asm-x86_64/vga.h2
-rw-r--r--include/asm-xtensa/vga.h2
-rw-r--r--include/linux/dcache.h2
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/key.h23
-rw-r--r--include/linux/pci.h4
-rw-r--r--include/linux/pci_ids.h11
-rw-r--r--include/linux/pci_regs.h1
-rw-r--r--include/linux/security.h10
-rw-r--r--include/linux/zconf.h12
-rw-r--r--include/linux/zlib.h209
-rw-r--r--include/linux/zutil.h12
-rw-r--r--include/sound/ac97_codec.h1
-rw-r--r--include/sound/asequencer.h4
-rw-r--r--include/sound/asound.h2
-rw-r--r--include/sound/core.h3
-rw-r--r--include/sound/emu10k1.h2
-rw-r--r--include/sound/info.h11
-rw-r--r--include/sound/mpu401.h14
-rw-r--r--include/sound/pcm.h19
-rw-r--r--include/sound/pcm_params.h125
-rw-r--r--include/sound/rawmidi.h3
-rw-r--r--include/sound/version.h4
-rw-r--r--kernel/power/main.c2
-rw-r--r--kernel/sys.c56
-rw-r--r--kernel/user.c2
-rw-r--r--lib/zlib_deflate/deflate.c25
-rw-r--r--lib/zlib_deflate/deflate_syms.c3
-rw-r--r--lib/zlib_inflate/Makefile4
-rw-r--r--lib/zlib_inflate/infblock.c365
-rw-r--r--lib/zlib_inflate/infblock.h48
-rw-r--r--lib/zlib_inflate/infcodes.c202
-rw-r--r--lib/zlib_inflate/infcodes.h33
-rw-r--r--lib/zlib_inflate/inffast.c462
-rw-r--r--lib/zlib_inflate/inffast.h12
-rw-r--r--lib/zlib_inflate/inffixed.h94
-rw-r--r--lib/zlib_inflate/inflate.c1086
-rw-r--r--lib/zlib_inflate/inflate.h107
-rw-r--r--lib/zlib_inflate/inflate_syms.c3
-rw-r--r--lib/zlib_inflate/inflate_sync.c152
-rw-r--r--lib/zlib_inflate/inftrees.c683
-rw-r--r--lib/zlib_inflate/inftrees.h99
-rw-r--r--lib/zlib_inflate/infutil.c88
-rw-r--r--lib/zlib_inflate/infutil.h176
-rw-r--r--security/dummy.c2
-rw-r--r--security/keys/key.c12
-rw-r--r--security/keys/keyring.c5
-rw-r--r--security/keys/process_keys.c57
-rw-r--r--security/keys/request_key.c6
-rw-r--r--security/keys/request_key_auth.c47
-rw-r--r--security/selinux/hooks.c64
-rw-r--r--security/selinux/include/av_perm_to_string.h6
-rw-r--r--security/selinux/include/av_permissions.h8
-rw-r--r--security/selinux/include/class_to_string.h1
-rw-r--r--security/selinux/include/flask.h1
-rw-r--r--security/selinux/include/objsec.h5
-rw-r--r--sound/Kconfig2
-rw-r--r--sound/Makefile2
-rw-r--r--sound/aoa/Kconfig17
-rw-r--r--sound/aoa/Makefile4
-rw-r--r--sound/aoa/aoa-gpio.h81
-rw-r--r--sound/aoa/aoa.h131
-rw-r--r--sound/aoa/codecs/Kconfig32
-rw-r--r--sound/aoa/codecs/Makefile3
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-onyx.c1113
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-onyx.h76
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h209
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-tas.c654
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-tas.h47
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-toonie.c141
-rw-r--r--sound/aoa/core/Makefile5
-rw-r--r--sound/aoa/core/snd-aoa-alsa.c98
-rw-r--r--sound/aoa/core/snd-aoa-alsa.h16
-rw-r--r--sound/aoa/core/snd-aoa-core.c162
-rw-r--r--sound/aoa/core/snd-aoa-gpio-feature.c399
-rw-r--r--sound/aoa/core/snd-aoa-gpio-pmf.c246
-rw-r--r--sound/aoa/fabrics/Kconfig12
-rw-r--r--sound/aoa/fabrics/Makefile1
-rw-r--r--sound/aoa/fabrics/snd-aoa-fabric-layout.c1109
-rw-r--r--sound/aoa/soundbus/Kconfig14
-rw-r--r--sound/aoa/soundbus/Makefile3
-rw-r--r--sound/aoa/soundbus/core.c250
-rw-r--r--sound/aoa/soundbus/i2sbus/Makefile2
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus-control.c192
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus-control.h37
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus-core.c387
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus-interface.h187
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus-pcm.c1021
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus.h112
-rw-r--r--sound/aoa/soundbus/soundbus.h202
-rw-r--r--sound/aoa/soundbus/sysfs.c43
-rw-r--r--sound/arm/sa11xx-uda1341.c16
-rw-r--r--sound/core/control.c31
-rw-r--r--sound/core/device.c6
-rw-r--r--sound/core/hwdep.c1
-rw-r--r--sound/core/info.c178
-rw-r--r--sound/core/info_oss.c3
-rw-r--r--sound/core/init.c78
-rw-r--r--sound/core/isadma.c6
-rw-r--r--sound/core/memory.c5
-rw-r--r--sound/core/misc.c6
-rw-r--r--sound/core/oss/mixer_oss.c2
-rw-r--r--sound/core/oss/pcm_oss.c529
-rw-r--r--sound/core/pcm.c90
-rw-r--r--sound/core/pcm_compat.c4
-rw-r--r--sound/core/pcm_lib.c725
-rw-r--r--sound/core/pcm_memory.c14
-rw-r--r--sound/core/pcm_misc.c24
-rw-r--r--sound/core/pcm_native.c113
-rw-r--r--sound/core/rawmidi.c3
-rw-r--r--sound/core/seq/oss/seq_oss.c1
-rw-r--r--sound/core/seq/seq.c22
-rw-r--r--sound/core/seq/seq_clientmgr.c12
-rw-r--r--sound/core/seq/seq_device.c3
-rw-r--r--sound/core/seq/seq_dummy.c6
-rw-r--r--sound/core/seq/seq_info.c11
-rw-r--r--sound/core/seq/seq_lock.c2
-rw-r--r--sound/core/seq/seq_memory.c3
-rw-r--r--sound/core/seq/seq_midi.c11
-rw-r--r--sound/core/seq/seq_ports.c5
-rw-r--r--sound/core/seq/seq_virmidi.c4
-rw-r--r--sound/core/sound.c109
-rw-r--r--sound/core/sound_oss.c9
-rw-r--r--sound/core/timer.c6
-rw-r--r--sound/drivers/dummy.c4
-rw-r--r--sound/drivers/mpu401/mpu401.c4
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c186
-rw-r--r--sound/drivers/mtpav.c14
-rw-r--r--sound/drivers/opl3/opl3_lib.c19
-rw-r--r--sound/drivers/opl3/opl3_oss.c3
-rw-r--r--sound/drivers/opl3/opl3_seq.c4
-rw-r--r--sound/drivers/opl3/opl3_synth.c4
-rw-r--r--sound/drivers/opl4/opl4_lib.c12
-rw-r--r--sound/drivers/opl4/opl4_seq.c4
-rw-r--r--sound/drivers/serial-u16550.c4
-rw-r--r--sound/drivers/virmidi.c4
-rw-r--r--sound/drivers/vx/vx_core.c32
-rw-r--r--sound/drivers/vx/vx_hwdep.c3
-rw-r--r--sound/i2c/i2c.c17
-rw-r--r--sound/i2c/l3/uda1341.c4
-rw-r--r--sound/isa/gus/gus_irq.c2
-rw-r--r--sound/isa/gus/gus_mem.c6
-rw-r--r--sound/isa/gus/gus_synth.c4
-rw-r--r--sound/isa/gus/interwave.c4
-rw-r--r--sound/isa/opl3sa2.c12
-rw-r--r--sound/isa/opti9xx/miro.c2
-rw-r--r--sound/isa/sb/emu8000.c22
-rw-r--r--sound/isa/sb/emu8000_patch.c2
-rw-r--r--sound/isa/sb/sb16.c2
-rw-r--r--sound/isa/sb/sb16_csp.c2
-rw-r--r--sound/isa/sb/sb8_midi.c20
-rw-r--r--sound/isa/sscape.c3
-rw-r--r--sound/isa/wavefront/wavefront.c2
-rw-r--r--sound/pci/Kconfig9
-rw-r--r--sound/pci/ac97/ac97_codec.c61
-rw-r--r--sound/pci/ac97/ac97_patch.c19
-rw-r--r--sound/pci/ac97/ac97_pcm.c10
-rw-r--r--sound/pci/ac97/ac97_proc.c5
-rw-r--r--sound/pci/ac97/ak4531_codec.c2
-rw-r--r--sound/pci/ad1889.c2
-rw-r--r--sound/pci/ali5451/ali5451.c4
-rw-r--r--sound/pci/als4000.c4
-rw-r--r--sound/pci/atiixp.c2
-rw-r--r--sound/pci/atiixp_modem.c2
-rw-r--r--sound/pci/au88x0/au88x0.c12
-rw-r--r--sound/pci/au88x0/au88x0_mpu401.c11
-rw-r--r--sound/pci/au88x0/au88x0_xtalk.c29
-rw-r--r--sound/pci/azt3328.c234
-rw-r--r--sound/pci/azt3328.h36
-rw-r--r--sound/pci/bt87x.c8
-rw-r--r--sound/pci/ca0106/ca0106.h4
-rw-r--r--sound/pci/ca0106/ca0106_main.c57
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c181
-rw-r--r--sound/pci/ca0106/ca0106_proc.c17
-rw-r--r--sound/pci/cmipci.c10
-rw-r--r--sound/pci/cs4281.c16
-rw-r--r--sound/pci/cs46xx/cs46xx.c4
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c5
-rw-r--r--sound/pci/cs46xx/dsp_spos.c7
-rw-r--r--sound/pci/cs46xx/dsp_spos_scb_lib.c1
-rw-r--r--sound/pci/cs5535audio/Makefile4
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c41
-rw-r--r--sound/pci/cs5535audio/cs5535audio.h8
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c24
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pm.c123
-rw-r--r--sound/pci/emu10k1/emu10k1.c8
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c69
-rw-r--r--sound/pci/emu10k1/emu10k1x.c3
-rw-r--r--sound/pci/emu10k1/emumixer.c54
-rw-r--r--sound/pci/emu10k1/emuproc.c27
-rw-r--r--sound/pci/emu10k1/io.c4
-rw-r--r--sound/pci/emu10k1/memory.c8
-rw-r--r--sound/pci/emu10k1/p17v.h111
-rw-r--r--sound/pci/emu10k1/tina2.h8
-rw-r--r--sound/pci/emu10k1/voice.c4
-rw-r--r--sound/pci/ens1370.c2
-rw-r--r--sound/pci/es1938.c3
-rw-r--r--sound/pci/es1968.c5
-rw-r--r--sound/pci/fm801.c5
-rw-r--r--sound/pci/hda/Makefile2
-rw-r--r--sound/pci/hda/hda_codec.c41
-rw-r--r--sound/pci/hda/hda_intel.c20
-rw-r--r--sound/pci/hda/hda_patch.h3
-rw-r--r--sound/pci/hda/hda_proc.c6
-rw-r--r--sound/pci/hda/patch_analog.c61
-rw-r--r--sound/pci/hda/patch_atihdmi.c165
-rw-r--r--sound/pci/hda/patch_realtek.c30
-rw-r--r--sound/pci/hda/patch_sigmatel.c82
-rw-r--r--sound/pci/ice1712/aureon.c26
-rw-r--r--sound/pci/ice1712/aureon.h1
-rw-r--r--sound/pci/ice1712/ews.c3
-rw-r--r--sound/pci/ice1712/ice1712.c43
-rw-r--r--sound/pci/ice1712/ice1712.h5
-rw-r--r--sound/pci/ice1712/ice1724.c5
-rw-r--r--sound/pci/ice1712/pontis.c8
-rw-r--r--sound/pci/intel8x0.c10
-rw-r--r--sound/pci/intel8x0m.c4
-rw-r--r--sound/pci/korg1212/korg1212.c2
-rw-r--r--sound/pci/maestro3.c3
-rw-r--r--sound/pci/mixart/mixart.c1
-rw-r--r--sound/pci/pcxhr/pcxhr.c4
-rw-r--r--sound/pci/riptide/riptide.c6
-rw-r--r--sound/pci/rme32.c14
-rw-r--r--sound/pci/rme96.c44
-rw-r--r--sound/pci/rme9652/hdsp.c7
-rw-r--r--sound/pci/rme9652/hdspm.c2
-rw-r--r--sound/pci/rme9652/rme9652.c4
-rw-r--r--sound/pci/sonicvibes.c8
-rw-r--r--sound/pci/trident/trident.c3
-rw-r--r--sound/pci/trident/trident_main.c22
-rw-r--r--sound/pci/trident/trident_memory.c3
-rw-r--r--sound/pci/trident/trident_synth.c4
-rw-r--r--sound/pci/via82xx.c12
-rw-r--r--sound/pci/via82xx_modem.c2
-rw-r--r--sound/pci/ymfpci/ymfpci.c3
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_core.c2
-rw-r--r--sound/pcmcia/vx/vxp_ops.c2
-rw-r--r--sound/pcmcia/vx/vxpocket.c2
-rw-r--r--sound/ppc/Makefile2
-rw-r--r--sound/ppc/pmac.c44
-rw-r--r--sound/ppc/pmac.h3
-rw-r--r--sound/ppc/powermac.c21
-rw-r--r--sound/ppc/toonie.c378
-rw-r--r--sound/sparc/dbri.c8
-rw-r--r--sound/synth/emux/emux.c12
-rw-r--r--sound/synth/emux/emux_proc.c1
-rw-r--r--sound/synth/emux/emux_seq.c3
-rw-r--r--sound/synth/emux/emux_synth.c5
-rw-r--r--sound/synth/emux/soundfont.c6
-rw-r--r--sound/usb/usbaudio.c15
-rw-r--r--sound/usb/usbaudio.h7
-rw-r--r--sound/usb/usbmidi.c202
-rw-r--r--sound/usb/usbmixer.c70
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c2
328 files changed, 13507 insertions, 4914 deletions
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index aaa01b0e3ee9..3bbe157b45e4 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -19,6 +19,7 @@ This document has the following sections:
19 - Key overview 19 - Key overview
20 - Key service overview 20 - Key service overview
21 - Key access permissions 21 - Key access permissions
22 - SELinux support
22 - New procfs files 23 - New procfs files
23 - Userspace system call interface 24 - Userspace system call interface
24 - Kernel services 25 - Kernel services
@@ -232,6 +233,34 @@ For changing the ownership, group ID or permissions mask, being the owner of
232the key or having the sysadmin capability is sufficient. 233the key or having the sysadmin capability is sufficient.
233 234
234 235
236===============
237SELINUX SUPPORT
238===============
239
240The security class "key" has been added to SELinux so that mandatory access
241controls can be applied to keys created within various contexts. This support
242is preliminary, and is likely to change quite significantly in the near future.
243Currently, all of the basic permissions explained above are provided in SELinux
244as well; SE Linux is simply invoked after all basic permission checks have been
245performed.
246
247Each key is labeled with the same context as the task to which it belongs.
248Typically, this is the same task that was running when the key was created.
249The default keyrings are handled differently, but in a way that is very
250intuitive:
251
252 (*) The user and user session keyrings that are created when the user logs in
253 are currently labeled with the context of the login manager.
254
255 (*) The keyrings associated with new threads are each labeled with the context
256 of their associated thread, and both session and process keyrings are
257 handled similarly.
258
259Note, however, that the default keyrings associated with the root user are
260labeled with the default kernel context, since they are created early in the
261boot process, before root has a chance to log in.
262
263
235================ 264================
236NEW PROCFS FILES 265NEW PROCFS FILES
237================ 266================
@@ -935,6 +964,16 @@ The structure has a number of fields, some of which are mandatory:
935 It is not safe to sleep in this method; the caller may hold spinlocks. 964 It is not safe to sleep in this method; the caller may hold spinlocks.
936 965
937 966
967 (*) void (*revoke)(struct key *key);
968
969 This method is optional. It is called to discard part of the payload
970 data upon a key being revoked. The caller will have the key semaphore
971 write-locked.
972
973 It is safe to sleep in this method, though care should be taken to avoid
974 a deadlock against the key semaphore.
975
976
938 (*) void (*destroy)(struct key *key); 977 (*) void (*destroy)(struct key *key);
939 978
940 This method is optional. It is called to discard the payload data on a key 979 This method is optional. It is called to discard the payload data on a key
diff --git a/Documentation/pci.txt b/Documentation/pci.txt
index 66bbbf1d1ef6..3242e5c1ee9c 100644
--- a/Documentation/pci.txt
+++ b/Documentation/pci.txt
@@ -213,9 +213,17 @@ have been remapped by the kernel.
213 213
214 See Documentation/IO-mapping.txt for how to access device memory. 214 See Documentation/IO-mapping.txt for how to access device memory.
215 215
216 You still need to call request_region() for I/O regions and 216 The device driver needs to call pci_request_region() to make sure
217request_mem_region() for memory regions to make sure nobody else is using the 217no other device is already using the same resource. The driver is expected
218same device. 218to determine MMIO and IO Port resource availability _before_ calling
219pci_enable_device(). Conversely, drivers should call pci_release_region()
220_after_ calling pci_disable_device(). The idea is to prevent two devices
221colliding on the same address range.
222
223Generic flavors of pci_request_region() are request_mem_region()
224(for MMIO ranges) and request_region() (for IO Port ranges).
225Use these for address resources that are not described by "normal" PCI
226interfaces (e.g. BAR).
219 227
220 All interrupt handlers should be registered with SA_SHIRQ and use the devid 228 All interrupt handlers should be registered with SA_SHIRQ and use the devid
221to map IRQs to devices (remember that all PCI interrupts are shared). 229to map IRQs to devices (remember that all PCI interrupts are shared).
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 0ee2c7dfc482..87d76a5c73d0 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -366,7 +366,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
366 366
367 Module for C-Media CMI8338 and 8738 PCI sound cards. 367 Module for C-Media CMI8338 and 8738 PCI sound cards.
368 368
369 mpu_port - 0x300,0x310,0x320,0x330, 0 = disable (default) 369 mpu_port - 0x300,0x310,0x320,0x330 = legacy port,
370 1 = integrated PCI port,
371 0 = disable (default)
370 fm_port - 0x388 (default), 0 = disable (default) 372 fm_port - 0x388 (default), 0 = disable (default)
371 soft_ac3 - Software-conversion of raw SPDIF packets (model 033 only) 373 soft_ac3 - Software-conversion of raw SPDIF packets (model 033 only)
372 (default = 1) 374 (default = 1)
@@ -468,7 +470,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
468 470
469 Module for multifunction CS5535 companion PCI device 471 Module for multifunction CS5535 companion PCI device
470 472
471 This module supports multiple cards. 473 The power-management is supported.
472 474
473 Module snd-dt019x 475 Module snd-dt019x
474 ----------------- 476 -----------------
@@ -707,8 +709,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
707 Module snd-hda-intel 709 Module snd-hda-intel
708 -------------------- 710 --------------------
709 711
710 Module for Intel HD Audio (ICH6, ICH6M, ICH7), ATI SB450, 712 Module for Intel HD Audio (ICH6, ICH6M, ESB2, ICH7, ICH8),
711 VIA VT8251/VT8237A 713 ATI SB450, SB600, RS600,
714 VIA VT8251/VT8237A,
715 SIS966, ULI M5461
712 716
713 model - force the model name 717 model - force the model name
714 position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) 718 position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
@@ -778,6 +782,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
778 AD1981 782 AD1981
779 basic 3-jack (default) 783 basic 3-jack (default)
780 hp HP nx6320 784 hp HP nx6320
785 thinkpad Lenovo Thinkpad T60/X60/Z60
781 786
782 AD1986A 787 AD1986A
783 6stack 6-jack, separate surrounds (default) 788 6stack 6-jack, separate surrounds (default)
@@ -1633,9 +1638,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1633 1638
1634 About capture IBL, see the description of snd-vx222 module. 1639 About capture IBL, see the description of snd-vx222 module.
1635 1640
1636 Note: the driver is build only when CONFIG_ISA is set. 1641 Note: snd-vxp440 driver is merged to snd-vxpocket driver since
1637
1638 Note2: snd-vxp440 driver is merged to snd-vxpocket driver since
1639 ALSA 1.0.10. 1642 ALSA 1.0.10.
1640 1643
1641 The power-management is supported. 1644 The power-management is supported.
@@ -1662,8 +1665,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1662 1665
1663 Module for Sound Core PDAudioCF sound card. 1666 Module for Sound Core PDAudioCF sound card.
1664 1667
1665 Note: the driver is build only when CONFIG_ISA is set.
1666
1667 The power-management is supported. 1668 The power-management is supported.
1668 1669
1669 1670
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 1faf76383bab..635cbb94357c 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -4215,7 +4215,7 @@ struct _snd_pcm_runtime {
4215 <programlisting> 4215 <programlisting>
4216<![CDATA[ 4216<![CDATA[
4217 struct snd_rawmidi *rmidi; 4217 struct snd_rawmidi *rmidi;
4218 snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, integrated, 4218 snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,
4219 irq, irq_flags, &rmidi); 4219 irq, irq_flags, &rmidi);
4220]]> 4220]]>
4221 </programlisting> 4221 </programlisting>
@@ -4242,15 +4242,36 @@ struct _snd_pcm_runtime {
4242 </para> 4242 </para>
4243 4243
4244 <para> 4244 <para>
4245 The 5th argument is bitflags for additional information.
4245 When the i/o port address above is a part of the PCI i/o 4246 When the i/o port address above is a part of the PCI i/o
4246 region, the MPU401 i/o port might have been already allocated 4247 region, the MPU401 i/o port might have been already allocated
4247 (reserved) by the driver itself. In such a case, pass non-zero 4248 (reserved) by the driver itself. In such a case, pass a bit flag
4248 to the 5th argument 4249 <constant>MPU401_INFO_INTEGRATED</constant>,
4249 (<parameter>integrated</parameter>). Otherwise, pass 0 to it,
4250 and 4250 and
4251 the mpu401-uart layer will allocate the i/o ports by itself. 4251 the mpu401-uart layer will allocate the i/o ports by itself.
4252 </para> 4252 </para>
4253 4253
4254 <para>
4255 When the controller supports only the input or output MIDI stream,
4256 pass <constant>MPU401_INFO_INPUT</constant> or
4257 <constant>MPU401_INFO_OUTPUT</constant> bitflag, respectively.
4258 Then the rawmidi instance is created as a single stream.
4259 </para>
4260
4261 <para>
4262 <constant>MPU401_INFO_MMIO</constant> bitflag is used to change
4263 the access method to MMIO (via readb and writeb) instead of
4264 iob and outb. In this case, you have to pass the iomapped address
4265 to <function>snd_mpu401_uart_new()</function>.
4266 </para>
4267
4268 <para>
4269 When <constant>MPU401_INFO_TX_IRQ</constant> is set, the output
4270 stream isn't checked in the default interrupt handler. The driver
4271 needs to call <function>snd_mpu401_uart_interrupt_tx()</function>
4272 by itself to start processing the output stream in irq handler.
4273 </para>
4274
4254 <para> 4275 <para>
4255 Usually, the port address corresponds to the command port and 4276 Usually, the port address corresponds to the command port and
4256 port + 1 corresponds to the data port. If not, you may change 4277 port + 1 corresponds to the data port. If not, you may change
@@ -5333,7 +5354,7 @@ struct _snd_pcm_runtime {
5333 <informalexample> 5354 <informalexample>
5334 <programlisting> 5355 <programlisting>
5335<![CDATA[ 5356<![CDATA[
5336 snd_info_set_text_ops(entry, chip, read_size, my_proc_read); 5357 snd_info_set_text_ops(entry, chip, my_proc_read);
5337]]> 5358]]>
5338 </programlisting> 5359 </programlisting>
5339 </informalexample> 5360 </informalexample>
@@ -5394,7 +5415,6 @@ struct _snd_pcm_runtime {
5394 <informalexample> 5415 <informalexample>
5395 <programlisting> 5416 <programlisting>
5396<![CDATA[ 5417<![CDATA[
5397 entry->c.text.write_size = 256;
5398 entry->c.text.write = my_proc_write; 5418 entry->c.text.write = my_proc_write;
5399]]> 5419]]>
5400 </programlisting> 5420 </programlisting>
@@ -5402,22 +5422,6 @@ struct _snd_pcm_runtime {
5402 </para> 5422 </para>
5403 5423
5404 <para> 5424 <para>
5405 The buffer size for read is set to 1024 implicitly by
5406 <function>snd_info_set_text_ops()</function>. It should suffice
5407 in most cases (the size will be aligned to
5408 <constant>PAGE_SIZE</constant> anyway), but if you need to handle
5409 very large text files, you can set it explicitly, too.
5410
5411 <informalexample>
5412 <programlisting>
5413<![CDATA[
5414 entry->c.text.read_size = 65536;
5415]]>
5416 </programlisting>
5417 </informalexample>
5418 </para>
5419
5420 <para>
5421 For the write callback, you can use 5425 For the write callback, you can use
5422 <function>snd_info_get_line()</function> to get a text line, and 5426 <function>snd_info_get_line()</function> to get a text line, and
5423 <function>snd_info_get_str()</function> to retrieve a string from 5427 <function>snd_info_get_str()</function> to retrieve a string from
@@ -5562,7 +5566,7 @@ struct _snd_pcm_runtime {
5562 power status.</para></listitem> 5566 power status.</para></listitem>
5563 <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem> 5567 <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem>
5564 <listitem><para>If AC97 codecs are used, call 5568 <listitem><para>If AC97 codecs are used, call
5565 <function>snd_ac97_resume()</function> for each codec.</para></listitem> 5569 <function>snd_ac97_suspend()</function> for each codec.</para></listitem>
5566 <listitem><para>Save the register values if necessary.</para></listitem> 5570 <listitem><para>Save the register values if necessary.</para></listitem>
5567 <listitem><para>Stop the hardware if necessary.</para></listitem> 5571 <listitem><para>Stop the hardware if necessary.</para></listitem>
5568 <listitem><para>Disable the PCI device by calling 5572 <listitem><para>Disable the PCI device by calling
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 40e5aba3ad3d..fbe93084244c 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -202,6 +202,8 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
202 if (mcfg->config[i].base_reserved) { 202 if (mcfg->config[i].base_reserved) {
203 printk(KERN_ERR PREFIX 203 printk(KERN_ERR PREFIX
204 "MMCONFIG not in low 4GB of memory\n"); 204 "MMCONFIG not in low 4GB of memory\n");
205 kfree(pci_mmcfg_config);
206 pci_mmcfg_config_num = 0;
205 return -ENODEV; 207 return -ENODEV;
206 } 208 }
207 } 209 }
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
index dbece776c5b2..c624b61e1104 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -288,6 +288,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
288 288
289void pcibios_disable_device (struct pci_dev *dev) 289void pcibios_disable_device (struct pci_dev *dev)
290{ 290{
291 pcibios_disable_resources(dev);
291 if (pcibios_disable_irq) 292 if (pcibios_disable_irq)
292 pcibios_disable_irq(dev); 293 pcibios_disable_irq(dev);
293} 294}
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c
index ed2c8c899bd3..7852827a599b 100644
--- a/arch/i386/pci/i386.c
+++ b/arch/i386/pci/i386.c
@@ -242,6 +242,15 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask)
242 return 0; 242 return 0;
243} 243}
244 244
245void pcibios_disable_resources(struct pci_dev *dev)
246{
247 u16 cmd;
248
249 pci_read_config_word(dev, PCI_COMMAND, &cmd);
250 cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
251 pci_write_config_word(dev, PCI_COMMAND, cmd);
252}
253
245/* 254/*
246 * If we set up a device for bus mastering, we need to check the latency 255 * If we set up a device for bus mastering, we need to check the latency
247 * timer as certain crappy BIOSes forget to set it properly. 256 * timer as certain crappy BIOSes forget to set it properly.
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index 6b1ea0c9a570..e545b0992c48 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -15,7 +15,9 @@
15#include <asm/e820.h> 15#include <asm/e820.h>
16#include "pci.h" 16#include "pci.h"
17 17
18#define MMCONFIG_APER_SIZE (256*1024*1024) 18/* aperture is up to 256MB but BIOS may reserve less */
19#define MMCONFIG_APER_MIN (2 * 1024*1024)
20#define MMCONFIG_APER_MAX (256 * 1024*1024)
19 21
20/* Assume systems with more busses have correct MCFG */ 22/* Assume systems with more busses have correct MCFG */
21#define MAX_CHECK_BUS 16 23#define MAX_CHECK_BUS 16
@@ -197,9 +199,10 @@ void __init pci_mmcfg_init(void)
197 return; 199 return;
198 200
199 if (!e820_all_mapped(pci_mmcfg_config[0].base_address, 201 if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
200 pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, 202 pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
201 E820_RESERVED)) { 203 E820_RESERVED)) {
202 printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); 204 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
205 pci_mmcfg_config[0].base_address);
203 printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); 206 printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
204 return; 207 return;
205 } 208 }
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h
index 12035e29108b..12bf3d8dda29 100644
--- a/arch/i386/pci/pci.h
+++ b/arch/i386/pci/pci.h
@@ -35,6 +35,7 @@ extern unsigned int pcibios_max_latency;
35 35
36void pcibios_resource_survey(void); 36void pcibios_resource_survey(void);
37int pcibios_enable_resources(struct pci_dev *, int); 37int pcibios_enable_resources(struct pci_dev *, int);
38void pcibios_disable_resources(struct pci_dev *);
38 39
39/* pci-pc.c */ 40/* pci-pc.c */
40 41
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 6c4d59fd0364..ef9a2b49307a 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -46,6 +46,10 @@
46 46
47#define IRQ_DEBUG 0 47#define IRQ_DEBUG 0
48 48
49/* These can be overridden in platform_irq_init */
50int ia64_first_device_vector = IA64_DEF_FIRST_DEVICE_VECTOR;
51int ia64_last_device_vector = IA64_DEF_LAST_DEVICE_VECTOR;
52
49/* default base addr of IPI table */ 53/* default base addr of IPI table */
50void __iomem *ipi_base_addr = ((void __iomem *) 54void __iomem *ipi_base_addr = ((void __iomem *)
51 (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR)); 55 (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR));
@@ -60,7 +64,7 @@ __u8 isa_irq_to_vector_map[16] = {
60}; 64};
61EXPORT_SYMBOL(isa_irq_to_vector_map); 65EXPORT_SYMBOL(isa_irq_to_vector_map);
62 66
63static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)]; 67static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_MAX_DEVICE_VECTORS)];
64 68
65int 69int
66assign_irq_vector (int irq) 70assign_irq_vector (int irq)
@@ -89,6 +93,19 @@ free_irq_vector (int vector)
89 printk(KERN_WARNING "%s: double free!\n", __FUNCTION__); 93 printk(KERN_WARNING "%s: double free!\n", __FUNCTION__);
90} 94}
91 95
96int
97reserve_irq_vector (int vector)
98{
99 int pos;
100
101 if (vector < IA64_FIRST_DEVICE_VECTOR ||
102 vector > IA64_LAST_DEVICE_VECTOR)
103 return -EINVAL;
104
105 pos = vector - IA64_FIRST_DEVICE_VECTOR;
106 return test_and_set_bit(pos, ia64_vector_mask);
107}
108
92#ifdef CONFIG_SMP 109#ifdef CONFIG_SMP
93# define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE) 110# define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE)
94#else 111#else
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 5101ac462643..dc09a6a28a37 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -58,7 +58,7 @@ static int max_pcibus_number = 255; /* Default highest pci bus number */
58 */ 58 */
59 59
60static dma_addr_t 60static dma_addr_t
61sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size) 61sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type)
62{ 62{
63 return 0; 63 return 0;
64} 64}
@@ -457,13 +457,6 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
457 pcidev_info->pdi_sn_irq_info = NULL; 457 pcidev_info->pdi_sn_irq_info = NULL;
458 kfree(sn_irq_info); 458 kfree(sn_irq_info);
459 } 459 }
460
461 /*
462 * MSI currently not supported on altix. Remove this when
463 * the MSI abstraction patches are integrated into the kernel
464 * (sometime after 2.6.16 releases)
465 */
466 dev->no_msi = 1;
467} 460}
468 461
469/* 462/*
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index c265e02f5036..dc8e2b696713 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -26,11 +26,11 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info);
26 26
27int sn_force_interrupt_flag = 1; 27int sn_force_interrupt_flag = 1;
28extern int sn_ioif_inited; 28extern int sn_ioif_inited;
29static struct list_head **sn_irq_lh; 29struct list_head **sn_irq_lh;
30static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ 30static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */
31 31
32static inline u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, 32u64 sn_intr_alloc(nasid_t local_nasid, int local_widget,
33 u64 sn_irq_info, 33 struct sn_irq_info *sn_irq_info,
34 int req_irq, nasid_t req_nasid, 34 int req_irq, nasid_t req_nasid,
35 int req_slice) 35 int req_slice)
36{ 36{
@@ -40,12 +40,13 @@ static inline u64 sn_intr_alloc(nasid_t local_nasid, int local_widget,
40 40
41 SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT, 41 SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT,
42 (u64) SAL_INTR_ALLOC, (u64) local_nasid, 42 (u64) SAL_INTR_ALLOC, (u64) local_nasid,
43 (u64) local_widget, (u64) sn_irq_info, (u64) req_irq, 43 (u64) local_widget, __pa(sn_irq_info), (u64) req_irq,
44 (u64) req_nasid, (u64) req_slice); 44 (u64) req_nasid, (u64) req_slice);
45
45 return ret_stuff.status; 46 return ret_stuff.status;
46} 47}
47 48
48static inline void sn_intr_free(nasid_t local_nasid, int local_widget, 49void sn_intr_free(nasid_t local_nasid, int local_widget,
49 struct sn_irq_info *sn_irq_info) 50 struct sn_irq_info *sn_irq_info)
50{ 51{
51 struct ia64_sal_retval ret_stuff; 52 struct ia64_sal_retval ret_stuff;
@@ -112,73 +113,91 @@ static void sn_end_irq(unsigned int irq)
112 113
113static void sn_irq_info_free(struct rcu_head *head); 114static void sn_irq_info_free(struct rcu_head *head);
114 115
115static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) 116struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info,
117 nasid_t nasid, int slice)
116{ 118{
117 struct sn_irq_info *sn_irq_info, *sn_irq_info_safe; 119 int vector;
118 int cpuid, cpuphys; 120 int cpuphys;
121 int64_t bridge;
122 int local_widget, status;
123 nasid_t local_nasid;
124 struct sn_irq_info *new_irq_info;
125 struct sn_pcibus_provider *pci_provider;
119 126
120 cpuid = first_cpu(mask); 127 new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC);
121 cpuphys = cpu_physical_id(cpuid); 128 if (new_irq_info == NULL)
129 return NULL;
122 130
123 list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, 131 memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info));
124 sn_irq_lh[irq], list) { 132
125 u64 bridge; 133 bridge = (u64) new_irq_info->irq_bridge;
126 int local_widget, status; 134 if (!bridge) {
127 nasid_t local_nasid; 135 kfree(new_irq_info);
128 struct sn_irq_info *new_irq_info; 136 return NULL; /* irq is not a device interrupt */
129 struct sn_pcibus_provider *pci_provider; 137 }
130
131 new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC);
132 if (new_irq_info == NULL)
133 break;
134 memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info));
135
136 bridge = (u64) new_irq_info->irq_bridge;
137 if (!bridge) {
138 kfree(new_irq_info);
139 break; /* irq is not a device interrupt */
140 }
141 138
142 local_nasid = NASID_GET(bridge); 139 local_nasid = NASID_GET(bridge);
143 140
144 if (local_nasid & 1) 141 if (local_nasid & 1)
145 local_widget = TIO_SWIN_WIDGETNUM(bridge); 142 local_widget = TIO_SWIN_WIDGETNUM(bridge);
146 else 143 else
147 local_widget = SWIN_WIDGETNUM(bridge); 144 local_widget = SWIN_WIDGETNUM(bridge);
148 145
149 /* Free the old PROM new_irq_info structure */ 146 vector = sn_irq_info->irq_irq;
150 sn_intr_free(local_nasid, local_widget, new_irq_info); 147 /* Free the old PROM new_irq_info structure */
151 /* Update kernels new_irq_info with new target info */ 148 sn_intr_free(local_nasid, local_widget, new_irq_info);
152 unregister_intr_pda(new_irq_info); 149 /* Update kernels new_irq_info with new target info */
150 unregister_intr_pda(new_irq_info);
153 151
154 /* allocate a new PROM new_irq_info struct */ 152 /* allocate a new PROM new_irq_info struct */
155 status = sn_intr_alloc(local_nasid, local_widget, 153 status = sn_intr_alloc(local_nasid, local_widget,
156 __pa(new_irq_info), irq, 154 new_irq_info, vector,
157 cpuid_to_nasid(cpuid), 155 nasid, slice);
158 cpuid_to_slice(cpuid));
159 156
160 /* SAL call failed */ 157 /* SAL call failed */
161 if (status) { 158 if (status) {
162 kfree(new_irq_info); 159 kfree(new_irq_info);
163 break; 160 return NULL;
164 } 161 }
165 162
166 new_irq_info->irq_cpuid = cpuid; 163 cpuphys = nasid_slice_to_cpuid(nasid, slice);
167 register_intr_pda(new_irq_info); 164 new_irq_info->irq_cpuid = cpuphys;
165 register_intr_pda(new_irq_info);
168 166
169 pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; 167 pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type];
170 if (pci_provider && pci_provider->target_interrupt)
171 (pci_provider->target_interrupt)(new_irq_info);
172 168
173 spin_lock(&sn_irq_info_lock); 169 /*
174 list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); 170 * If this represents a line interrupt, target it. If it's
175 spin_unlock(&sn_irq_info_lock); 171 * an msi (irq_int_bit < 0), it's already targeted.
176 call_rcu(&sn_irq_info->rcu, sn_irq_info_free); 172 */
173 if (new_irq_info->irq_int_bit >= 0 &&
174 pci_provider && pci_provider->target_interrupt)
175 (pci_provider->target_interrupt)(new_irq_info);
176
177 spin_lock(&sn_irq_info_lock);
178 list_replace_rcu(&sn_irq_info->list, &new_irq_info->list);
179 spin_unlock(&sn_irq_info_lock);
180 call_rcu(&sn_irq_info->rcu, sn_irq_info_free);
177 181
178#ifdef CONFIG_SMP 182#ifdef CONFIG_SMP
179 set_irq_affinity_info((irq & 0xff), cpuphys, 0); 183 set_irq_affinity_info((vector & 0xff), cpuphys, 0);
180#endif 184#endif
181 } 185
186 return new_irq_info;
187}
188
189static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
190{
191 struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
192 nasid_t nasid;
193 int slice;
194
195 nasid = cpuid_to_nasid(first_cpu(mask));
196 slice = cpuid_to_slice(first_cpu(mask));
197
198 list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
199 sn_irq_lh[irq], list)
200 (void)sn_retarget_vector(sn_irq_info, nasid, slice);
182} 201}
183 202
184struct hw_interrupt_type irq_type_sn = { 203struct hw_interrupt_type irq_type_sn = {
@@ -202,6 +221,9 @@ void sn_irq_init(void)
202 int i; 221 int i;
203 irq_desc_t *base_desc = irq_desc; 222 irq_desc_t *base_desc = irq_desc;
204 223
224 ia64_first_device_vector = IA64_SN2_FIRST_DEVICE_VECTOR;
225 ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR;
226
205 for (i = 0; i < NR_IRQS; i++) { 227 for (i = 0; i < NR_IRQS; i++) {
206 if (base_desc[i].handler == &no_irq_type) { 228 if (base_desc[i].handler == &no_irq_type) {
207 base_desc[i].handler = &irq_type_sn; 229 base_desc[i].handler = &irq_type_sn;
@@ -285,6 +307,7 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info)
285 /* link it into the sn_irq[irq] list */ 307 /* link it into the sn_irq[irq] list */
286 spin_lock(&sn_irq_info_lock); 308 spin_lock(&sn_irq_info_lock);
287 list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); 309 list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]);
310 reserve_irq_vector(sn_irq_info->irq_irq);
288 spin_unlock(&sn_irq_info_lock); 311 spin_unlock(&sn_irq_info_lock);
289 312
290 register_intr_pda(sn_irq_info); 313 register_intr_pda(sn_irq_info);
@@ -310,8 +333,11 @@ void sn_irq_unfixup(struct pci_dev *pci_dev)
310 spin_lock(&sn_irq_info_lock); 333 spin_lock(&sn_irq_info_lock);
311 list_del_rcu(&sn_irq_info->list); 334 list_del_rcu(&sn_irq_info->list);
312 spin_unlock(&sn_irq_info_lock); 335 spin_unlock(&sn_irq_info_lock);
336 if (list_empty(sn_irq_lh[sn_irq_info->irq_irq]))
337 free_irq_vector(sn_irq_info->irq_irq);
313 call_rcu(&sn_irq_info->rcu, sn_irq_info_free); 338 call_rcu(&sn_irq_info->rcu, sn_irq_info_free);
314 pci_dev_put(pci_dev); 339 pci_dev_put(pci_dev);
340
315} 341}
316 342
317static inline void 343static inline void
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index b4b84c269210..7a291a271511 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -11,7 +11,7 @@
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <asm/dma.h> 13#include <asm/dma.h>
14#include <asm/sn/pcibr_provider.h> 14#include <asm/sn/intr.h>
15#include <asm/sn/pcibus_provider_defs.h> 15#include <asm/sn/pcibus_provider_defs.h>
16#include <asm/sn/pcidev.h> 16#include <asm/sn/pcidev.h>
17#include <asm/sn/sn_sal.h> 17#include <asm/sn/sn_sal.h>
@@ -113,7 +113,8 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size,
113 * resources. 113 * resources.
114 */ 114 */
115 115
116 *dma_handle = provider->dma_map_consistent(pdev, phys_addr, size); 116 *dma_handle = provider->dma_map_consistent(pdev, phys_addr, size,
117 SN_DMA_ADDR_PHYS);
117 if (!*dma_handle) { 118 if (!*dma_handle) {
118 printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); 119 printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__);
119 free_pages((unsigned long)cpuaddr, get_order(size)); 120 free_pages((unsigned long)cpuaddr, get_order(size));
@@ -176,7 +177,7 @@ dma_addr_t sn_dma_map_single(struct device *dev, void *cpu_addr, size_t size,
176 BUG_ON(dev->bus != &pci_bus_type); 177 BUG_ON(dev->bus != &pci_bus_type);
177 178
178 phys_addr = __pa(cpu_addr); 179 phys_addr = __pa(cpu_addr);
179 dma_addr = provider->dma_map(pdev, phys_addr, size); 180 dma_addr = provider->dma_map(pdev, phys_addr, size, SN_DMA_ADDR_PHYS);
180 if (!dma_addr) { 181 if (!dma_addr) {
181 printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); 182 printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__);
182 return 0; 183 return 0;
@@ -260,7 +261,8 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
260 for (i = 0; i < nhwentries; i++, sg++) { 261 for (i = 0; i < nhwentries; i++, sg++) {
261 phys_addr = SG_ENT_PHYS_ADDRESS(sg); 262 phys_addr = SG_ENT_PHYS_ADDRESS(sg);
262 sg->dma_address = provider->dma_map(pdev, 263 sg->dma_address = provider->dma_map(pdev,
263 phys_addr, sg->length); 264 phys_addr, sg->length,
265 SN_DMA_ADDR_PHYS);
264 266
265 if (!sg->dma_address) { 267 if (!sg->dma_address) {
266 printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); 268 printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__);
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
index 9f86bb6519aa..a86c7b945962 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
@@ -41,7 +41,7 @@ extern int sn_ioif_inited;
41 41
42static dma_addr_t 42static dma_addr_t
43pcibr_dmamap_ate32(struct pcidev_info *info, 43pcibr_dmamap_ate32(struct pcidev_info *info,
44 u64 paddr, size_t req_size, u64 flags) 44 u64 paddr, size_t req_size, u64 flags, int dma_flags)
45{ 45{
46 46
47 struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; 47 struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info;
@@ -81,9 +81,12 @@ pcibr_dmamap_ate32(struct pcidev_info *info,
81 if (IS_PCIX(pcibus_info)) 81 if (IS_PCIX(pcibus_info))
82 ate_flags &= ~(PCI32_ATE_PREF); 82 ate_flags &= ~(PCI32_ATE_PREF);
83 83
84 xio_addr = 84 if (SN_DMA_ADDRTYPE(dma_flags == SN_DMA_ADDR_PHYS))
85 IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : 85 xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) :
86 PHYS_TO_TIODMA(paddr); 86 PHYS_TO_TIODMA(paddr);
87 else
88 xio_addr = paddr;
89
87 offset = IOPGOFF(xio_addr); 90 offset = IOPGOFF(xio_addr);
88 ate = ate_flags | (xio_addr - offset); 91 ate = ate_flags | (xio_addr - offset);
89 92
@@ -91,6 +94,13 @@ pcibr_dmamap_ate32(struct pcidev_info *info,
91 if (IS_PIC_SOFT(pcibus_info)) { 94 if (IS_PIC_SOFT(pcibus_info)) {
92 ate |= (pcibus_info->pbi_hub_xid << PIC_ATE_TARGETID_SHFT); 95 ate |= (pcibus_info->pbi_hub_xid << PIC_ATE_TARGETID_SHFT);
93 } 96 }
97
98 /*
99 * If we're mapping for MSI, set the MSI bit in the ATE
100 */
101 if (dma_flags & SN_DMA_MSI)
102 ate |= PCI32_ATE_MSI;
103
94 ate_write(pcibus_info, ate_index, ate_count, ate); 104 ate_write(pcibus_info, ate_index, ate_count, ate);
95 105
96 /* 106 /*
@@ -105,20 +115,27 @@ pcibr_dmamap_ate32(struct pcidev_info *info,
105 if (pcibus_info->pbi_devreg[internal_device] & PCIBR_DEV_SWAP_DIR) 115 if (pcibus_info->pbi_devreg[internal_device] & PCIBR_DEV_SWAP_DIR)
106 ATE_SWAP_ON(pci_addr); 116 ATE_SWAP_ON(pci_addr);
107 117
118
108 return pci_addr; 119 return pci_addr;
109} 120}
110 121
111static dma_addr_t 122static dma_addr_t
112pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, 123pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr,
113 u64 dma_attributes) 124 u64 dma_attributes, int dma_flags)
114{ 125{
115 struct pcibus_info *pcibus_info = (struct pcibus_info *) 126 struct pcibus_info *pcibus_info = (struct pcibus_info *)
116 ((info->pdi_host_pcidev_info)->pdi_pcibus_info); 127 ((info->pdi_host_pcidev_info)->pdi_pcibus_info);
117 u64 pci_addr; 128 u64 pci_addr;
118 129
119 /* Translate to Crosstalk View of Physical Address */ 130 /* Translate to Crosstalk View of Physical Address */
120 pci_addr = (IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : 131 if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS)
121 PHYS_TO_TIODMA(paddr)) | dma_attributes; 132 pci_addr = IS_PIC_SOFT(pcibus_info) ?
133 PHYS_TO_DMA(paddr) :
134 PHYS_TO_TIODMA(paddr) | dma_attributes;
135 else
136 pci_addr = IS_PIC_SOFT(pcibus_info) ?
137 paddr :
138 paddr | dma_attributes;
122 139
123 /* Handle Bus mode */ 140 /* Handle Bus mode */
124 if (IS_PCIX(pcibus_info)) 141 if (IS_PCIX(pcibus_info))
@@ -130,7 +147,9 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr,
130 ((u64) pcibus_info-> 147 ((u64) pcibus_info->
131 pbi_hub_xid << PIC_PCI64_ATTR_TARG_SHFT); 148 pbi_hub_xid << PIC_PCI64_ATTR_TARG_SHFT);
132 } else 149 } else
133 pci_addr |= TIOCP_PCI64_CMDTYPE_MEM; 150 pci_addr |= (dma_flags & SN_DMA_MSI) ?
151 TIOCP_PCI64_CMDTYPE_MSI :
152 TIOCP_PCI64_CMDTYPE_MEM;
134 153
135 /* If PCI mode, func zero uses VCHAN0, every other func uses VCHAN1 */ 154 /* If PCI mode, func zero uses VCHAN0, every other func uses VCHAN1 */
136 if (!IS_PCIX(pcibus_info) && PCI_FUNC(info->pdi_linux_pcidev->devfn)) 155 if (!IS_PCIX(pcibus_info) && PCI_FUNC(info->pdi_linux_pcidev->devfn))
@@ -141,7 +160,7 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr,
141 160
142static dma_addr_t 161static dma_addr_t
143pcibr_dmatrans_direct32(struct pcidev_info * info, 162pcibr_dmatrans_direct32(struct pcidev_info * info,
144 u64 paddr, size_t req_size, u64 flags) 163 u64 paddr, size_t req_size, u64 flags, int dma_flags)
145{ 164{
146 struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; 165 struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info;
147 struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> 166 struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info->
@@ -156,8 +175,14 @@ pcibr_dmatrans_direct32(struct pcidev_info * info,
156 return 0; 175 return 0;
157 } 176 }
158 177
159 xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : 178 if (dma_flags & SN_DMA_MSI)
160 PHYS_TO_TIODMA(paddr); 179 return 0;
180
181 if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS)
182 xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) :
183 PHYS_TO_TIODMA(paddr);
184 else
185 xio_addr = paddr;
161 186
162 xio_base = pcibus_info->pbi_dir_xbase; 187 xio_base = pcibus_info->pbi_dir_xbase;
163 offset = xio_addr - xio_base; 188 offset = xio_addr - xio_base;
@@ -327,7 +352,7 @@ void sn_dma_flush(u64 addr)
327 */ 352 */
328 353
329dma_addr_t 354dma_addr_t
330pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size) 355pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size, int dma_flags)
331{ 356{
332 dma_addr_t dma_handle; 357 dma_addr_t dma_handle;
333 struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev); 358 struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);
@@ -344,11 +369,11 @@ pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size)
344 */ 369 */
345 370
346 dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr, 371 dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr,
347 PCI64_ATTR_PREF); 372 PCI64_ATTR_PREF, dma_flags);
348 } else { 373 } else {
349 /* Handle 32-63 bit cards via direct mapping */ 374 /* Handle 32-63 bit cards via direct mapping */
350 dma_handle = pcibr_dmatrans_direct32(pcidev_info, phys_addr, 375 dma_handle = pcibr_dmatrans_direct32(pcidev_info, phys_addr,
351 size, 0); 376 size, 0, dma_flags);
352 if (!dma_handle) { 377 if (!dma_handle) {
353 /* 378 /*
354 * It is a 32 bit card and we cannot do direct mapping, 379 * It is a 32 bit card and we cannot do direct mapping,
@@ -356,7 +381,8 @@ pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size)
356 */ 381 */
357 382
358 dma_handle = pcibr_dmamap_ate32(pcidev_info, phys_addr, 383 dma_handle = pcibr_dmamap_ate32(pcidev_info, phys_addr,
359 size, PCI32_ATE_PREF); 384 size, PCI32_ATE_PREF,
385 dma_flags);
360 } 386 }
361 } 387 }
362 388
@@ -365,18 +391,18 @@ pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size)
365 391
366dma_addr_t 392dma_addr_t
367pcibr_dma_map_consistent(struct pci_dev * hwdev, unsigned long phys_addr, 393pcibr_dma_map_consistent(struct pci_dev * hwdev, unsigned long phys_addr,
368 size_t size) 394 size_t size, int dma_flags)
369{ 395{
370 dma_addr_t dma_handle; 396 dma_addr_t dma_handle;
371 struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev); 397 struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);
372 398
373 if (hwdev->dev.coherent_dma_mask == ~0UL) { 399 if (hwdev->dev.coherent_dma_mask == ~0UL) {
374 dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr, 400 dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr,
375 PCI64_ATTR_BAR); 401 PCI64_ATTR_BAR, dma_flags);
376 } else { 402 } else {
377 dma_handle = (dma_addr_t) pcibr_dmamap_ate32(pcidev_info, 403 dma_handle = (dma_addr_t) pcibr_dmamap_ate32(pcidev_info,
378 phys_addr, size, 404 phys_addr, size,
379 PCI32_ATE_BAR); 405 PCI32_ATE_BAR, dma_flags);
380 } 406 }
381 407
382 return dma_handle; 408 return dma_handle;
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index be0176912968..20de72791b97 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -515,11 +515,17 @@ tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
515 * use the GART mapped mode. 515 * use the GART mapped mode.
516 */ 516 */
517static u64 517static u64
518tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count) 518tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags)
519{ 519{
520 u64 mapaddr; 520 u64 mapaddr;
521 521
522 /* 522 /*
523 * Not supported for now ...
524 */
525 if (dma_flags & SN_DMA_MSI)
526 return 0;
527
528 /*
523 * If card is 64 or 48 bit addresable, use a direct mapping. 32 529 * If card is 64 or 48 bit addresable, use a direct mapping. 32
524 * bit direct is so restrictive w.r.t. where the memory resides that 530 * bit direct is so restrictive w.r.t. where the memory resides that
525 * we don't use it even though CA has some support. 531 * we don't use it even though CA has some support.
diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c
index 833295624e5d..4cac7bdc7c7f 100644
--- a/arch/ia64/sn/pci/tioce_provider.c
+++ b/arch/ia64/sn/pci/tioce_provider.c
@@ -170,7 +170,8 @@ tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr)
170 (ATE_PAGE((start)+(len)-1, pagesize) - ATE_PAGE(start, pagesize) + 1) 170 (ATE_PAGE((start)+(len)-1, pagesize) - ATE_PAGE(start, pagesize) + 1)
171 171
172#define ATE_VALID(ate) ((ate) & (1UL << 63)) 172#define ATE_VALID(ate) ((ate) & (1UL << 63))
173#define ATE_MAKE(addr, ps) (((addr) & ~ATE_PAGEMASK(ps)) | (1UL << 63)) 173#define ATE_MAKE(addr, ps, msi) \
174 (((addr) & ~ATE_PAGEMASK(ps)) | (1UL << 63) | ((msi)?(1UL << 62):0))
174 175
175/* 176/*
176 * Flavors of ate-based mapping supported by tioce_alloc_map() 177 * Flavors of ate-based mapping supported by tioce_alloc_map()
@@ -196,15 +197,17 @@ tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr)
196 * 197 *
197 * 63 - must be 1 to indicate d64 mode to CE hardware 198 * 63 - must be 1 to indicate d64 mode to CE hardware
198 * 62 - barrier bit ... controlled with tioce_dma_barrier() 199 * 62 - barrier bit ... controlled with tioce_dma_barrier()
199 * 61 - 0 since this is not an MSI transaction 200 * 61 - msi bit ... specified through dma_flags
200 * 60:54 - reserved, MBZ 201 * 60:54 - reserved, MBZ
201 */ 202 */
202static u64 203static u64
203tioce_dma_d64(unsigned long ct_addr) 204tioce_dma_d64(unsigned long ct_addr, int dma_flags)
204{ 205{
205 u64 bus_addr; 206 u64 bus_addr;
206 207
207 bus_addr = ct_addr | (1UL << 63); 208 bus_addr = ct_addr | (1UL << 63);
209 if (dma_flags & SN_DMA_MSI)
210 bus_addr |= (1UL << 61);
208 211
209 return bus_addr; 212 return bus_addr;
210} 213}
@@ -261,7 +264,7 @@ pcidev_to_tioce(struct pci_dev *pdev, struct tioce **base,
261 */ 264 */
262static u64 265static u64
263tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, 266tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
264 u64 ct_addr, int len) 267 u64 ct_addr, int len, int dma_flags)
265{ 268{
266 int i; 269 int i;
267 int j; 270 int j;
@@ -270,6 +273,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
270 int entries; 273 int entries;
271 int nates; 274 int nates;
272 u64 pagesize; 275 u64 pagesize;
276 int msi_capable, msi_wanted;
273 u64 *ate_shadow; 277 u64 *ate_shadow;
274 u64 *ate_reg; 278 u64 *ate_reg;
275 u64 addr; 279 u64 addr;
@@ -291,6 +295,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
291 ate_reg = ce_mmr->ce_ure_ate3240; 295 ate_reg = ce_mmr->ce_ure_ate3240;
292 pagesize = ce_kern->ce_ate3240_pagesize; 296 pagesize = ce_kern->ce_ate3240_pagesize;
293 bus_base = TIOCE_M32_MIN; 297 bus_base = TIOCE_M32_MIN;
298 msi_capable = 1;
294 break; 299 break;
295 case TIOCE_ATE_M40: 300 case TIOCE_ATE_M40:
296 first = 0; 301 first = 0;
@@ -299,6 +304,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
299 ate_reg = ce_mmr->ce_ure_ate40; 304 ate_reg = ce_mmr->ce_ure_ate40;
300 pagesize = MB(64); 305 pagesize = MB(64);
301 bus_base = TIOCE_M40_MIN; 306 bus_base = TIOCE_M40_MIN;
307 msi_capable = 0;
302 break; 308 break;
303 case TIOCE_ATE_M40S: 309 case TIOCE_ATE_M40S:
304 /* 310 /*
@@ -311,11 +317,16 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
311 ate_reg = ce_mmr->ce_ure_ate3240; 317 ate_reg = ce_mmr->ce_ure_ate3240;
312 pagesize = GB(16); 318 pagesize = GB(16);
313 bus_base = TIOCE_M40S_MIN; 319 bus_base = TIOCE_M40S_MIN;
320 msi_capable = 0;
314 break; 321 break;
315 default: 322 default:
316 return 0; 323 return 0;
317 } 324 }
318 325
326 msi_wanted = dma_flags & SN_DMA_MSI;
327 if (msi_wanted && !msi_capable)
328 return 0;
329
319 nates = ATE_NPAGES(ct_addr, len, pagesize); 330 nates = ATE_NPAGES(ct_addr, len, pagesize);
320 if (nates > entries) 331 if (nates > entries)
321 return 0; 332 return 0;
@@ -344,7 +355,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
344 for (j = 0; j < nates; j++) { 355 for (j = 0; j < nates; j++) {
345 u64 ate; 356 u64 ate;
346 357
347 ate = ATE_MAKE(addr, pagesize); 358 ate = ATE_MAKE(addr, pagesize, msi_wanted);
348 ate_shadow[i + j] = ate; 359 ate_shadow[i + j] = ate;
349 tioce_mmr_storei(ce_kern, &ate_reg[i + j], ate); 360 tioce_mmr_storei(ce_kern, &ate_reg[i + j], ate);
350 addr += pagesize; 361 addr += pagesize;
@@ -371,7 +382,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
371 * Map @paddr into 32-bit bus space of the CE associated with @pcidev_info. 382 * Map @paddr into 32-bit bus space of the CE associated with @pcidev_info.
372 */ 383 */
373static u64 384static u64
374tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr) 385tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr, int dma_flags)
375{ 386{
376 int dma_ok; 387 int dma_ok;
377 int port; 388 int port;
@@ -381,6 +392,9 @@ tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr)
381 u64 ct_lower; 392 u64 ct_lower;
382 dma_addr_t bus_addr; 393 dma_addr_t bus_addr;
383 394
395 if (dma_flags & SN_DMA_MSI)
396 return 0;
397
384 ct_upper = ct_addr & ~0x3fffffffUL; 398 ct_upper = ct_addr & ~0x3fffffffUL;
385 ct_lower = ct_addr & 0x3fffffffUL; 399 ct_lower = ct_addr & 0x3fffffffUL;
386 400
@@ -507,7 +521,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
507 */ 521 */
508static u64 522static u64
509tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, 523tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count,
510 int barrier) 524 int barrier, int dma_flags)
511{ 525{
512 unsigned long flags; 526 unsigned long flags;
513 u64 ct_addr; 527 u64 ct_addr;
@@ -523,15 +537,18 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count,
523 if (dma_mask < 0x7fffffffUL) 537 if (dma_mask < 0x7fffffffUL)
524 return 0; 538 return 0;
525 539
526 ct_addr = PHYS_TO_TIODMA(paddr); 540 if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS)
541 ct_addr = PHYS_TO_TIODMA(paddr);
542 else
543 ct_addr = paddr;
527 544
528 /* 545 /*
529 * If the device can generate 64 bit addresses, create a D64 map. 546 * If the device can generate 64 bit addresses, create a D64 map.
530 * Since this should never fail, bypass the rest of the checks.
531 */ 547 */
532 if (dma_mask == ~0UL) { 548 if (dma_mask == ~0UL) {
533 mapaddr = tioce_dma_d64(ct_addr); 549 mapaddr = tioce_dma_d64(ct_addr, dma_flags);
534 goto dma_map_done; 550 if (mapaddr)
551 goto dma_map_done;
535 } 552 }
536 553
537 pcidev_to_tioce(pdev, NULL, &ce_kern, &port); 554 pcidev_to_tioce(pdev, NULL, &ce_kern, &port);
@@ -574,18 +591,22 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count,
574 591
575 if (byte_count > MB(64)) { 592 if (byte_count > MB(64)) {
576 mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40S, 593 mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40S,
577 port, ct_addr, byte_count); 594 port, ct_addr, byte_count,
595 dma_flags);
578 if (!mapaddr) 596 if (!mapaddr)
579 mapaddr = 597 mapaddr =
580 tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1, 598 tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1,
581 ct_addr, byte_count); 599 ct_addr, byte_count,
600 dma_flags);
582 } else { 601 } else {
583 mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1, 602 mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1,
584 ct_addr, byte_count); 603 ct_addr, byte_count,
604 dma_flags);
585 if (!mapaddr) 605 if (!mapaddr)
586 mapaddr = 606 mapaddr =
587 tioce_alloc_map(ce_kern, TIOCE_ATE_M40S, 607 tioce_alloc_map(ce_kern, TIOCE_ATE_M40S,
588 port, ct_addr, byte_count); 608 port, ct_addr, byte_count,
609 dma_flags);
589 } 610 }
590 } 611 }
591 612
@@ -593,7 +614,7 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count,
593 * 32-bit direct is the next mode to try 614 * 32-bit direct is the next mode to try
594 */ 615 */
595 if (!mapaddr && dma_mask >= 0xffffffffUL) 616 if (!mapaddr && dma_mask >= 0xffffffffUL)
596 mapaddr = tioce_dma_d32(pdev, ct_addr); 617 mapaddr = tioce_dma_d32(pdev, ct_addr, dma_flags);
597 618
598 /* 619 /*
599 * Last resort, try 32-bit ATE-based map. 620 * Last resort, try 32-bit ATE-based map.
@@ -601,7 +622,7 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count,
601 if (!mapaddr) 622 if (!mapaddr)
602 mapaddr = 623 mapaddr =
603 tioce_alloc_map(ce_kern, TIOCE_ATE_M32, -1, ct_addr, 624 tioce_alloc_map(ce_kern, TIOCE_ATE_M32, -1, ct_addr,
604 byte_count); 625 byte_count, dma_flags);
605 626
606 spin_unlock_irqrestore(&ce_kern->ce_lock, flags); 627 spin_unlock_irqrestore(&ce_kern->ce_lock, flags);
607 628
@@ -622,9 +643,9 @@ dma_map_done:
622 * in the address. 643 * in the address.
623 */ 644 */
624static u64 645static u64
625tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count) 646tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags)
626{ 647{
627 return tioce_do_dma_map(pdev, paddr, byte_count, 0); 648 return tioce_do_dma_map(pdev, paddr, byte_count, 0, dma_flags);
628} 649}
629 650
630/** 651/**
@@ -636,9 +657,9 @@ tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count)
636 * Simply call tioce_do_dma_map() to create a map with the barrier bit set 657 * Simply call tioce_do_dma_map() to create a map with the barrier bit set
637 * in the address. 658 * in the address.
638 */ static u64 659 */ static u64
639tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count) 660tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags)
640{ 661{
641 return tioce_do_dma_map(pdev, paddr, byte_count, 1); 662 return tioce_do_dma_map(pdev, paddr, byte_count, 1, dma_flags);
642} 663}
643 664
644/** 665/**
@@ -696,7 +717,7 @@ tioce_reserve_m32(struct tioce_kernel *ce_kern, u64 base, u64 limit)
696 while (ate_index <= last_ate) { 717 while (ate_index <= last_ate) {
697 u64 ate; 718 u64 ate;
698 719
699 ate = ATE_MAKE(0xdeadbeef, ps); 720 ate = ATE_MAKE(0xdeadbeef, ps, 0);
700 ce_kern->ce_ate3240_shadow[ate_index] = ate; 721 ce_kern->ce_ate3240_shadow[ate_index] = ate;
701 tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_ate3240[ate_index], 722 tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_ate3240[ate_index],
702 ate); 723 ate);
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 840ae595a617..d961bfeed05f 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -29,8 +29,8 @@ OBJCOPYFLAGS := contents,alloc,load,readonly,data
29OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000 29OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000
30OBJCOPY_MIB_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment 30OBJCOPY_MIB_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
31 31
32zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c 32zlib := inffast.c inflate.c inftrees.c
33zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h 33zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
34zliblinuxheader := zlib.h zconf.h zutil.h 34zliblinuxheader := zlib.h zconf.h zutil.h
35 35
36$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) 36$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
diff --git a/arch/ppc/boot/lib/Makefile b/arch/ppc/boot/lib/Makefile
index 80c84d562fa4..2f995f712ec5 100644
--- a/arch/ppc/boot/lib/Makefile
+++ b/arch/ppc/boot/lib/Makefile
@@ -5,7 +5,7 @@
5CFLAGS_kbd.o := -Idrivers/char 5CFLAGS_kbd.o := -Idrivers/char
6CFLAGS_vreset.o := -Iarch/ppc/boot/include 6CFLAGS_vreset.o := -Iarch/ppc/boot/include
7 7
8zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c 8zlib := inffast.c inflate.c inftrees.c
9 9
10lib-y += $(zlib:.c=.o) div64.o 10lib-y += $(zlib:.c=.o) div64.o
11lib-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o 11lib-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index c9e0aeeca3d8..4368dc3f3c30 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -379,13 +379,12 @@ mpc85xx_cds_pcibios_fixup(void)
379 PCI_DEVICE_ID_VIA_82C586_2, NULL))) { 379 PCI_DEVICE_ID_VIA_82C586_2, NULL))) {
380 dev->irq = 10; 380 dev->irq = 10;
381 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10); 381 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10);
382 pci_dev_put(dev);
383 }
384 382
385 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, 383 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
386 PCI_DEVICE_ID_VIA_82C586_2, dev))) { 384 PCI_DEVICE_ID_VIA_82C586_2, dev))) {
387 dev->irq = 11; 385 dev->irq = 11;
388 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); 386 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
387 }
389 pci_dev_put(dev); 388 pci_dev_put(dev);
390 } 389 }
391} 390}
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 2cbf282f0d00..a893a9cc9534 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -332,7 +332,7 @@ void __init setup_arch(char **cmdline_p)
332 if (!root_flags) 332 if (!root_flags)
333 root_mountflags &= ~MS_RDONLY; 333 root_mountflags &= ~MS_RDONLY;
334 ROOT_DEV = old_decode_dev(root_dev); 334 ROOT_DEV = old_decode_dev(root_dev);
335#ifdef CONFIG_BLK_DEV_INITRD 335#ifdef CONFIG_BLK_DEV_RAM
336 rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK; 336 rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
337 rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0); 337 rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0);
338 rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0); 338 rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0);
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index 86f51d04c98d..87cdbc560d36 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -87,7 +87,7 @@ void timer_irq(union uml_pt_regs *regs)
87 87
88void time_init_kern(void) 88void time_init_kern(void)
89{ 89{
90 unsigned long long nsecs; 90 long long nsecs;
91 91
92 nsecs = os_nsecs(); 92 nsecs = os_nsecs();
93 set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, 93 set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 408d44a59756..7d3bc5ac5db0 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -389,6 +389,7 @@ config GART_IOMMU
389 bool "K8 GART IOMMU support" 389 bool "K8 GART IOMMU support"
390 default y 390 default y
391 select SWIOTLB 391 select SWIOTLB
392 select AGP
392 depends on PCI 393 depends on PCI
393 help 394 help
394 Support for hardware IOMMU in AMD's Opteron/Athlon64 Processors 395 Support for hardware IOMMU in AMD's Opteron/Athlon64 Processors
@@ -401,11 +402,9 @@ config GART_IOMMU
401 northbridge and a software emulation used on other systems without 402 northbridge and a software emulation used on other systems without
402 hardware IOMMU. If unsure, say Y. 403 hardware IOMMU. If unsure, say Y.
403 404
404# need this always enabled with GART_IOMMU for the VIA workaround 405# need this always selected by GART_IOMMU for the VIA workaround
405config SWIOTLB 406config SWIOTLB
406 bool 407 bool
407 default y
408 depends on GART_IOMMU
409 408
410config X86_MCE 409config X86_MCE
411 bool "Machine check support" if EMBEDDED 410 bool "Machine check support" if EMBEDDED
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
index a2060e4d5de6..3c55c76c6fd5 100644
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -13,7 +13,10 @@
13 13
14#include "pci.h" 14#include "pci.h"
15 15
16#define MMCONFIG_APER_SIZE (256*1024*1024) 16/* aperture is up to 256MB but BIOS may reserve less */
17#define MMCONFIG_APER_MIN (2 * 1024*1024)
18#define MMCONFIG_APER_MAX (256 * 1024*1024)
19
17/* Verify the first 16 busses. We assume that systems with more busses 20/* Verify the first 16 busses. We assume that systems with more busses
18 get MCFG right. */ 21 get MCFG right. */
19#define MAX_CHECK_BUS 16 22#define MAX_CHECK_BUS 16
@@ -175,9 +178,10 @@ void __init pci_mmcfg_init(void)
175 return; 178 return;
176 179
177 if (!e820_all_mapped(pci_mmcfg_config[0].base_address, 180 if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
178 pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, 181 pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
179 E820_RESERVED)) { 182 E820_RESERVED)) {
180 printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); 183 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
184 pci_mmcfg_config[0].base_address);
181 printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); 185 printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
182 return; 186 return;
183 } 187 }
@@ -190,7 +194,8 @@ void __init pci_mmcfg_init(void)
190 } 194 }
191 for (i = 0; i < pci_mmcfg_config_num; ++i) { 195 for (i = 0; i < pci_mmcfg_config_num; ++i) {
192 pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; 196 pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
193 pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE); 197 pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address,
198 MMCONFIG_APER_MAX);
194 if (!pci_mmcfg_virt[i].virt) { 199 if (!pci_mmcfg_virt[i].virt) {
195 printk("PCI: Cannot map mmconfig aperture for segment %d\n", 200 printk("PCI: Cannot map mmconfig aperture for segment %d\n",
196 pci_mmcfg_config[i].pci_segment_group_number); 201 pci_mmcfg_config[i].pci_segment_group_number);
diff --git a/arch/xtensa/boot/lib/Makefile b/arch/xtensa/boot/lib/Makefile
index 9e73bb8aeb7a..d3d2aa2d883a 100644
--- a/arch/xtensa/boot/lib/Makefile
+++ b/arch/xtensa/boot/lib/Makefile
@@ -2,7 +2,7 @@
2# Makefile for some libs needed by zImage. 2# Makefile for some libs needed by zImage.
3# 3#
4 4
5zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c 5zlib := inffast.c inflate.c inftrees.c
6 6
7lib-y += $(zlib:.c=.o) zmem.o 7lib-y += $(zlib:.c=.o) zmem.o
8 8
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index 7c88c060a9e6..46685a540772 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -1,7 +1,6 @@
1config AGP 1config AGP
2 tristate "/dev/agpgart (AGP Support)" if !GART_IOMMU 2 tristate "/dev/agpgart (AGP Support)"
3 depends on ALPHA || IA64 || PPC || X86 3 depends on ALPHA || IA64 || PPC || X86
4 default y if GART_IOMMU
5 ---help--- 4 ---help---
6 AGP (Accelerated Graphics Port) is a bus system mainly used to 5 AGP (Accelerated Graphics Port) is a bus system mainly used to
7 connect graphics cards to the rest of the system. 6 connect graphics cards to the rest of the system.
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index e1feb58bd661..1a2b9785e998 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -2120,7 +2120,7 @@ abort_linearize:
2120 goto drop; 2120 goto drop;
2121 } 2121 }
2122 2122
2123 if (skb_linearize(skb, GFP_ATOMIC)) 2123 if (skb_linearize(skb))
2124 goto drop; 2124 goto drop;
2125 2125
2126 mgp->tx_linearized++; 2126 mgp->tx_linearized++;
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 6707df968934..f2d152b818f0 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -26,7 +26,11 @@ obj-$(CONFIG_PPC32) += setup-irq.o
26obj-$(CONFIG_PPC64) += setup-bus.o 26obj-$(CONFIG_PPC64) += setup-bus.o
27obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o 27obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
28obj-$(CONFIG_X86_VISWS) += setup-irq.o 28obj-$(CONFIG_X86_VISWS) += setup-irq.o
29obj-$(CONFIG_PCI_MSI) += msi.o 29
30msiobj-y := msi.o msi-apic.o
31msiobj-$(CONFIG_IA64_GENERIC) += msi-altix.o
32msiobj-$(CONFIG_IA64_SGI_SN2) += msi-altix.o
33obj-$(CONFIG_PCI_MSI) += $(msiobj-y)
30 34
31# 35#
32# ACPI Related PCI FW Functions 36# ACPI Related PCI FW Functions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index eed67d9e73bc..723092682023 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -81,9 +81,9 @@ void __devinit pci_bus_add_device(struct pci_dev *dev)
81{ 81{
82 device_add(&dev->dev); 82 device_add(&dev->dev);
83 83
84 spin_lock(&pci_bus_lock); 84 down_write(&pci_bus_sem);
85 list_add_tail(&dev->global_list, &pci_devices); 85 list_add_tail(&dev->global_list, &pci_devices);
86 spin_unlock(&pci_bus_lock); 86 up_write(&pci_bus_sem);
87 87
88 pci_proc_attach_device(dev); 88 pci_proc_attach_device(dev);
89 pci_create_sysfs_dev_files(dev); 89 pci_create_sysfs_dev_files(dev);
@@ -125,10 +125,10 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus)
125 */ 125 */
126 if (dev->subordinate) { 126 if (dev->subordinate) {
127 if (list_empty(&dev->subordinate->node)) { 127 if (list_empty(&dev->subordinate->node)) {
128 spin_lock(&pci_bus_lock); 128 down_write(&pci_bus_sem);
129 list_add_tail(&dev->subordinate->node, 129 list_add_tail(&dev->subordinate->node,
130 &dev->bus->children); 130 &dev->bus->children);
131 spin_unlock(&pci_bus_lock); 131 up_write(&pci_bus_sem);
132 } 132 }
133 pci_bus_add_devices(dev->subordinate); 133 pci_bus_add_devices(dev->subordinate);
134 134
@@ -168,7 +168,7 @@ void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
168 struct list_head *next; 168 struct list_head *next;
169 169
170 bus = top; 170 bus = top;
171 spin_lock(&pci_bus_lock); 171 down_read(&pci_bus_sem);
172 next = top->devices.next; 172 next = top->devices.next;
173 for (;;) { 173 for (;;) {
174 if (next == &bus->devices) { 174 if (next == &bus->devices) {
@@ -180,22 +180,19 @@ void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
180 continue; 180 continue;
181 } 181 }
182 dev = list_entry(next, struct pci_dev, bus_list); 182 dev = list_entry(next, struct pci_dev, bus_list);
183 pci_dev_get(dev);
184 if (dev->subordinate) { 183 if (dev->subordinate) {
185 /* this is a pci-pci bridge, do its devices next */ 184 /* this is a pci-pci bridge, do its devices next */
186 next = dev->subordinate->devices.next; 185 next = dev->subordinate->devices.next;
187 bus = dev->subordinate; 186 bus = dev->subordinate;
188 } else 187 } else
189 next = dev->bus_list.next; 188 next = dev->bus_list.next;
190 spin_unlock(&pci_bus_lock);
191 189
192 /* Run device routines with the bus unlocked */ 190 /* Run device routines with the device locked */
191 down(&dev->dev.sem);
193 cb(dev, userdata); 192 cb(dev, userdata);
194 193 up(&dev->dev.sem);
195 spin_lock(&pci_bus_lock);
196 pci_dev_put(dev);
197 } 194 }
198 spin_unlock(&pci_bus_lock); 195 up_read(&pci_bus_sem);
199} 196}
200EXPORT_SYMBOL_GPL(pci_walk_bus); 197EXPORT_SYMBOL_GPL(pci_walk_bus);
201 198
diff --git a/drivers/pci/msi-altix.c b/drivers/pci/msi-altix.c
new file mode 100644
index 000000000000..bed4183a5e39
--- /dev/null
+++ b/drivers/pci/msi-altix.c
@@ -0,0 +1,210 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved.
7 */
8
9#include <linux/types.h>
10#include <linux/pci.h>
11#include <linux/cpumask.h>
12
13#include <asm/sn/addrs.h>
14#include <asm/sn/intr.h>
15#include <asm/sn/pcibus_provider_defs.h>
16#include <asm/sn/pcidev.h>
17#include <asm/sn/nodepda.h>
18
19#include "msi.h"
20
21struct sn_msi_info {
22 u64 pci_addr;
23 struct sn_irq_info *sn_irq_info;
24};
25
26static struct sn_msi_info *sn_msi_info;
27
28static void
29sn_msi_teardown(unsigned int vector)
30{
31 nasid_t nasid;
32 int widget;
33 struct pci_dev *pdev;
34 struct pcidev_info *sn_pdev;
35 struct sn_irq_info *sn_irq_info;
36 struct pcibus_bussoft *bussoft;
37 struct sn_pcibus_provider *provider;
38
39 sn_irq_info = sn_msi_info[vector].sn_irq_info;
40 if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
41 return;
42
43 sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
44 pdev = sn_pdev->pdi_linux_pcidev;
45 provider = SN_PCIDEV_BUSPROVIDER(pdev);
46
47 (*provider->dma_unmap)(pdev,
48 sn_msi_info[vector].pci_addr,
49 PCI_DMA_FROMDEVICE);
50 sn_msi_info[vector].pci_addr = 0;
51
52 bussoft = SN_PCIDEV_BUSSOFT(pdev);
53 nasid = NASID_GET(bussoft->bs_base);
54 widget = (nasid & 1) ?
55 TIO_SWIN_WIDGETNUM(bussoft->bs_base) :
56 SWIN_WIDGETNUM(bussoft->bs_base);
57
58 sn_intr_free(nasid, widget, sn_irq_info);
59 sn_msi_info[vector].sn_irq_info = NULL;
60
61 return;
62}
63
64int
65sn_msi_setup(struct pci_dev *pdev, unsigned int vector,
66 u32 *addr_hi, u32 *addr_lo, u32 *data)
67{
68 int widget;
69 int status;
70 nasid_t nasid;
71 u64 bus_addr;
72 struct sn_irq_info *sn_irq_info;
73 struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev);
74 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
75
76 if (bussoft == NULL)
77 return -EINVAL;
78
79 if (provider == NULL || provider->dma_map_consistent == NULL)
80 return -EINVAL;
81
82 /*
83 * Set up the vector plumbing. Let the prom (via sn_intr_alloc)
84 * decide which cpu to direct this msi at by default.
85 */
86
87 nasid = NASID_GET(bussoft->bs_base);
88 widget = (nasid & 1) ?
89 TIO_SWIN_WIDGETNUM(bussoft->bs_base) :
90 SWIN_WIDGETNUM(bussoft->bs_base);
91
92 sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
93 if (! sn_irq_info)
94 return -ENOMEM;
95
96 status = sn_intr_alloc(nasid, widget, sn_irq_info, vector, -1, -1);
97 if (status) {
98 kfree(sn_irq_info);
99 return -ENOMEM;
100 }
101
102 sn_irq_info->irq_int_bit = -1; /* mark this as an MSI irq */
103 sn_irq_fixup(pdev, sn_irq_info);
104
105 /* Prom probably should fill these in, but doesn't ... */
106 sn_irq_info->irq_bridge_type = bussoft->bs_asic_type;
107 sn_irq_info->irq_bridge = (void *)bussoft->bs_base;
108
109 /*
110 * Map the xio address into bus space
111 */
112 bus_addr = (*provider->dma_map_consistent)(pdev,
113 sn_irq_info->irq_xtalkaddr,
114 sizeof(sn_irq_info->irq_xtalkaddr),
115 SN_DMA_MSI|SN_DMA_ADDR_XIO);
116 if (! bus_addr) {
117 sn_intr_free(nasid, widget, sn_irq_info);
118 kfree(sn_irq_info);
119 return -ENOMEM;
120 }
121
122 sn_msi_info[vector].sn_irq_info = sn_irq_info;
123 sn_msi_info[vector].pci_addr = bus_addr;
124
125 *addr_hi = (u32)(bus_addr >> 32);
126 *addr_lo = (u32)(bus_addr & 0x00000000ffffffff);
127
128 /*
129 * In the SN platform, bit 16 is a "send vector" bit which
130 * must be present in order to move the vector through the system.
131 */
132 *data = 0x100 + (unsigned int)vector;
133
134#ifdef CONFIG_SMP
135 set_irq_affinity_info((vector & 0xff), sn_irq_info->irq_cpuid, 0);
136#endif
137
138 return 0;
139}
140
141static void
142sn_msi_target(unsigned int vector, unsigned int cpu,
143 u32 *addr_hi, u32 *addr_lo)
144{
145 int slice;
146 nasid_t nasid;
147 u64 bus_addr;
148 struct pci_dev *pdev;
149 struct pcidev_info *sn_pdev;
150 struct sn_irq_info *sn_irq_info;
151 struct sn_irq_info *new_irq_info;
152 struct sn_pcibus_provider *provider;
153
154 sn_irq_info = sn_msi_info[vector].sn_irq_info;
155 if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
156 return;
157
158 /*
159 * Release XIO resources for the old MSI PCI address
160 */
161
162 sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
163 pdev = sn_pdev->pdi_linux_pcidev;
164 provider = SN_PCIDEV_BUSPROVIDER(pdev);
165
166 bus_addr = (u64)(*addr_hi) << 32 | (u64)(*addr_lo);
167 (*provider->dma_unmap)(pdev, bus_addr, PCI_DMA_FROMDEVICE);
168 sn_msi_info[vector].pci_addr = 0;
169
170 nasid = cpuid_to_nasid(cpu);
171 slice = cpuid_to_slice(cpu);
172
173 new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice);
174 sn_msi_info[vector].sn_irq_info = new_irq_info;
175 if (new_irq_info == NULL)
176 return;
177
178 /*
179 * Map the xio address into bus space
180 */
181
182 bus_addr = (*provider->dma_map_consistent)(pdev,
183 new_irq_info->irq_xtalkaddr,
184 sizeof(new_irq_info->irq_xtalkaddr),
185 SN_DMA_MSI|SN_DMA_ADDR_XIO);
186
187 sn_msi_info[vector].pci_addr = bus_addr;
188 *addr_hi = (u32)(bus_addr >> 32);
189 *addr_lo = (u32)(bus_addr & 0x00000000ffffffff);
190}
191
192struct msi_ops sn_msi_ops = {
193 .setup = sn_msi_setup,
194 .teardown = sn_msi_teardown,
195#ifdef CONFIG_SMP
196 .target = sn_msi_target,
197#endif
198};
199
200int
201sn_msi_init(void)
202{
203 sn_msi_info =
204 kzalloc(sizeof(struct sn_msi_info) * NR_VECTORS, GFP_KERNEL);
205 if (! sn_msi_info)
206 return -ENOMEM;
207
208 msi_register(&sn_msi_ops);
209 return 0;
210}
diff --git a/drivers/pci/msi-apic.c b/drivers/pci/msi-apic.c
new file mode 100644
index 000000000000..0eb5fe9003a2
--- /dev/null
+++ b/drivers/pci/msi-apic.c
@@ -0,0 +1,100 @@
1/*
2 * MSI hooks for standard x86 apic
3 */
4
5#include <linux/pci.h>
6#include <linux/irq.h>
7
8#include "msi.h"
9
10/*
11 * Shifts for APIC-based data
12 */
13
14#define MSI_DATA_VECTOR_SHIFT 0
15#define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT)
16
17#define MSI_DATA_DELIVERY_SHIFT 8
18#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT)
19#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_SHIFT)
20
21#define MSI_DATA_LEVEL_SHIFT 14
22#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT)
23#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT)
24
25#define MSI_DATA_TRIGGER_SHIFT 15
26#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT)
27#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT)
28
29/*
30 * Shift/mask fields for APIC-based bus address
31 */
32
33#define MSI_ADDR_HEADER 0xfee00000
34
35#define MSI_ADDR_DESTID_MASK 0xfff0000f
36#define MSI_ADDR_DESTID_CPU(cpu) ((cpu) << MSI_TARGET_CPU_SHIFT)
37
38#define MSI_ADDR_DESTMODE_SHIFT 2
39#define MSI_ADDR_DESTMODE_PHYS (0 << MSI_ADDR_DESTMODE_SHIFT)
40#define MSI_ADDR_DESTMODE_LOGIC (1 << MSI_ADDR_DESTMODE_SHIFT)
41
42#define MSI_ADDR_REDIRECTION_SHIFT 3
43#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT)
44#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT)
45
46
47static void
48msi_target_apic(unsigned int vector,
49 unsigned int dest_cpu,
50 u32 *address_hi, /* in/out */
51 u32 *address_lo) /* in/out */
52{
53 u32 addr = *address_lo;
54
55 addr &= MSI_ADDR_DESTID_MASK;
56 addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(dest_cpu));
57
58 *address_lo = addr;
59}
60
61static int
62msi_setup_apic(struct pci_dev *pdev, /* unused in generic */
63 unsigned int vector,
64 u32 *address_hi,
65 u32 *address_lo,
66 u32 *data)
67{
68 unsigned long dest_phys_id;
69
70 dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
71
72 *address_hi = 0;
73 *address_lo = MSI_ADDR_HEADER |
74 MSI_ADDR_DESTMODE_PHYS |
75 MSI_ADDR_REDIRECTION_CPU |
76 MSI_ADDR_DESTID_CPU(dest_phys_id);
77
78 *data = MSI_DATA_TRIGGER_EDGE |
79 MSI_DATA_LEVEL_ASSERT |
80 MSI_DATA_DELIVERY_FIXED |
81 MSI_DATA_VECTOR(vector);
82
83 return 0;
84}
85
86static void
87msi_teardown_apic(unsigned int vector)
88{
89 return; /* no-op */
90}
91
92/*
93 * Generic ops used on most IA archs/platforms. Set with msi_register()
94 */
95
96struct msi_ops msi_apic_ops = {
97 .setup = msi_setup_apic,
98 .teardown = msi_teardown_apic,
99 .target = msi_target_apic,
100};
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 9855c4c920b8..7f8429284fab 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -23,8 +23,6 @@
23#include "pci.h" 23#include "pci.h"
24#include "msi.h" 24#include "msi.h"
25 25
26#define MSI_TARGET_CPU first_cpu(cpu_online_map)
27
28static DEFINE_SPINLOCK(msi_lock); 26static DEFINE_SPINLOCK(msi_lock);
29static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; 27static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
30static kmem_cache_t* msi_cachep; 28static kmem_cache_t* msi_cachep;
@@ -37,9 +35,17 @@ static int nr_msix_devices;
37 35
38#ifndef CONFIG_X86_IO_APIC 36#ifndef CONFIG_X86_IO_APIC
39int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; 37int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
40u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 };
41#endif 38#endif
42 39
40static struct msi_ops *msi_ops;
41
42int
43msi_register(struct msi_ops *ops)
44{
45 msi_ops = ops;
46 return 0;
47}
48
43static void msi_cache_ctor(void *p, kmem_cache_t *cache, unsigned long flags) 49static void msi_cache_ctor(void *p, kmem_cache_t *cache, unsigned long flags)
44{ 50{
45 memset(p, 0, NR_IRQS * sizeof(struct msi_desc)); 51 memset(p, 0, NR_IRQS * sizeof(struct msi_desc));
@@ -92,7 +98,7 @@ static void msi_set_mask_bit(unsigned int vector, int flag)
92static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) 98static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
93{ 99{
94 struct msi_desc *entry; 100 struct msi_desc *entry;
95 struct msg_address address; 101 u32 address_hi, address_lo;
96 unsigned int irq = vector; 102 unsigned int irq = vector;
97 unsigned int dest_cpu = first_cpu(cpu_mask); 103 unsigned int dest_cpu = first_cpu(cpu_mask);
98 104
@@ -108,28 +114,36 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
108 if (!pos) 114 if (!pos)
109 return; 115 return;
110 116
117 pci_read_config_dword(entry->dev, msi_upper_address_reg(pos),
118 &address_hi);
111 pci_read_config_dword(entry->dev, msi_lower_address_reg(pos), 119 pci_read_config_dword(entry->dev, msi_lower_address_reg(pos),
112 &address.lo_address.value); 120 &address_lo);
113 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; 121
114 address.lo_address.value |= (cpu_physical_id(dest_cpu) << 122 msi_ops->target(vector, dest_cpu, &address_hi, &address_lo);
115 MSI_TARGET_CPU_SHIFT); 123
116 entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu); 124 pci_write_config_dword(entry->dev, msi_upper_address_reg(pos),
125 address_hi);
117 pci_write_config_dword(entry->dev, msi_lower_address_reg(pos), 126 pci_write_config_dword(entry->dev, msi_lower_address_reg(pos),
118 address.lo_address.value); 127 address_lo);
119 set_native_irq_info(irq, cpu_mask); 128 set_native_irq_info(irq, cpu_mask);
120 break; 129 break;
121 } 130 }
122 case PCI_CAP_ID_MSIX: 131 case PCI_CAP_ID_MSIX:
123 { 132 {
124 int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + 133 int offset_hi =
125 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET; 134 entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
126 135 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET;
127 address.lo_address.value = readl(entry->mask_base + offset); 136 int offset_lo =
128 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; 137 entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
129 address.lo_address.value |= (cpu_physical_id(dest_cpu) << 138 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET;
130 MSI_TARGET_CPU_SHIFT); 139
131 entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu); 140 address_hi = readl(entry->mask_base + offset_hi);
132 writel(address.lo_address.value, entry->mask_base + offset); 141 address_lo = readl(entry->mask_base + offset_lo);
142
143 msi_ops->target(vector, dest_cpu, &address_hi, &address_lo);
144
145 writel(address_hi, entry->mask_base + offset_hi);
146 writel(address_lo, entry->mask_base + offset_lo);
133 set_native_irq_info(irq, cpu_mask); 147 set_native_irq_info(irq, cpu_mask);
134 break; 148 break;
135 } 149 }
@@ -251,30 +265,6 @@ static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
251 .set_affinity = set_msi_affinity 265 .set_affinity = set_msi_affinity
252}; 266};
253 267
254static void msi_data_init(struct msg_data *msi_data,
255 unsigned int vector)
256{
257 memset(msi_data, 0, sizeof(struct msg_data));
258 msi_data->vector = (u8)vector;
259 msi_data->delivery_mode = MSI_DELIVERY_MODE;
260 msi_data->level = MSI_LEVEL_MODE;
261 msi_data->trigger = MSI_TRIGGER_MODE;
262}
263
264static void msi_address_init(struct msg_address *msi_address)
265{
266 unsigned int dest_id;
267 unsigned long dest_phys_id = cpu_physical_id(MSI_TARGET_CPU);
268
269 memset(msi_address, 0, sizeof(struct msg_address));
270 msi_address->hi_address = (u32)0;
271 dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT);
272 msi_address->lo_address.u.dest_mode = MSI_PHYSICAL_MODE;
273 msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE;
274 msi_address->lo_address.u.dest_id = dest_id;
275 msi_address->lo_address.value |= (dest_phys_id << MSI_TARGET_CPU_SHIFT);
276}
277
278static int msi_free_vector(struct pci_dev* dev, int vector, int reassign); 268static int msi_free_vector(struct pci_dev* dev, int vector, int reassign);
279static int assign_msi_vector(void) 269static int assign_msi_vector(void)
280{ 270{
@@ -369,13 +359,29 @@ static int msi_init(void)
369 return status; 359 return status;
370 } 360 }
371 361
362 status = msi_arch_init();
363 if (status < 0) {
364 pci_msi_enable = 0;
365 printk(KERN_WARNING
366 "PCI: MSI arch init failed. MSI disabled.\n");
367 return status;
368 }
369
370 if (! msi_ops) {
371 printk(KERN_WARNING
372 "PCI: MSI ops not registered. MSI disabled.\n");
373 status = -EINVAL;
374 return status;
375 }
376
377 last_alloc_vector = assign_irq_vector(AUTO_ASSIGN);
372 status = msi_cache_init(); 378 status = msi_cache_init();
373 if (status < 0) { 379 if (status < 0) {
374 pci_msi_enable = 0; 380 pci_msi_enable = 0;
375 printk(KERN_WARNING "PCI: MSI cache init failed\n"); 381 printk(KERN_WARNING "PCI: MSI cache init failed\n");
376 return status; 382 return status;
377 } 383 }
378 last_alloc_vector = assign_irq_vector(AUTO_ASSIGN); 384
379 if (last_alloc_vector < 0) { 385 if (last_alloc_vector < 0) {
380 pci_msi_enable = 0; 386 pci_msi_enable = 0;
381 printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n"); 387 printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n");
@@ -442,9 +448,11 @@ static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
442 /* Set enabled bits to single MSI & enable MSI_enable bit */ 448 /* Set enabled bits to single MSI & enable MSI_enable bit */
443 msi_enable(control, 1); 449 msi_enable(control, 1);
444 pci_write_config_word(dev, msi_control_reg(pos), control); 450 pci_write_config_word(dev, msi_control_reg(pos), control);
451 dev->msi_enabled = 1;
445 } else { 452 } else {
446 msix_enable(control); 453 msix_enable(control);
447 pci_write_config_word(dev, msi_control_reg(pos), control); 454 pci_write_config_word(dev, msi_control_reg(pos), control);
455 dev->msix_enabled = 1;
448 } 456 }
449 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { 457 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
450 /* PCI Express Endpoint device detected */ 458 /* PCI Express Endpoint device detected */
@@ -461,9 +469,11 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type)
461 /* Set enabled bits to single MSI & enable MSI_enable bit */ 469 /* Set enabled bits to single MSI & enable MSI_enable bit */
462 msi_disable(control); 470 msi_disable(control);
463 pci_write_config_word(dev, msi_control_reg(pos), control); 471 pci_write_config_word(dev, msi_control_reg(pos), control);
472 dev->msi_enabled = 0;
464 } else { 473 } else {
465 msix_disable(control); 474 msix_disable(control);
466 pci_write_config_word(dev, msi_control_reg(pos), control); 475 pci_write_config_word(dev, msi_control_reg(pos), control);
476 dev->msix_enabled = 0;
467 } 477 }
468 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { 478 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
469 /* PCI Express Endpoint device detected */ 479 /* PCI Express Endpoint device detected */
@@ -538,7 +548,6 @@ int pci_save_msi_state(struct pci_dev *dev)
538 pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, &cap[i++]); 548 pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, &cap[i++]);
539 if (control & PCI_MSI_FLAGS_MASKBIT) 549 if (control & PCI_MSI_FLAGS_MASKBIT)
540 pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, &cap[i++]); 550 pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, &cap[i++]);
541 disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
542 save_state->cap_nr = PCI_CAP_ID_MSI; 551 save_state->cap_nr = PCI_CAP_ID_MSI;
543 pci_add_saved_cap(dev, save_state); 552 pci_add_saved_cap(dev, save_state);
544 return 0; 553 return 0;
@@ -575,6 +584,8 @@ void pci_restore_msi_state(struct pci_dev *dev)
575int pci_save_msix_state(struct pci_dev *dev) 584int pci_save_msix_state(struct pci_dev *dev)
576{ 585{
577 int pos; 586 int pos;
587 int temp;
588 int vector, head, tail = 0;
578 u16 control; 589 u16 control;
579 struct pci_cap_saved_state *save_state; 590 struct pci_cap_saved_state *save_state;
580 591
@@ -582,6 +593,7 @@ int pci_save_msix_state(struct pci_dev *dev)
582 if (pos <= 0 || dev->no_msi) 593 if (pos <= 0 || dev->no_msi)
583 return 0; 594 return 0;
584 595
596 /* save the capability */
585 pci_read_config_word(dev, msi_control_reg(pos), &control); 597 pci_read_config_word(dev, msi_control_reg(pos), &control);
586 if (!(control & PCI_MSIX_FLAGS_ENABLE)) 598 if (!(control & PCI_MSIX_FLAGS_ENABLE))
587 return 0; 599 return 0;
@@ -593,7 +605,38 @@ int pci_save_msix_state(struct pci_dev *dev)
593 } 605 }
594 *((u16 *)&save_state->data[0]) = control; 606 *((u16 *)&save_state->data[0]) = control;
595 607
596 disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); 608 /* save the table */
609 temp = dev->irq;
610 if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
611 kfree(save_state);
612 return -EINVAL;
613 }
614
615 vector = head = dev->irq;
616 while (head != tail) {
617 int j;
618 void __iomem *base;
619 struct msi_desc *entry;
620
621 entry = msi_desc[vector];
622 base = entry->mask_base;
623 j = entry->msi_attrib.entry_nr;
624
625 entry->address_lo_save =
626 readl(base + j * PCI_MSIX_ENTRY_SIZE +
627 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
628 entry->address_hi_save =
629 readl(base + j * PCI_MSIX_ENTRY_SIZE +
630 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
631 entry->data_save =
632 readl(base + j * PCI_MSIX_ENTRY_SIZE +
633 PCI_MSIX_ENTRY_DATA_OFFSET);
634
635 tail = msi_desc[vector]->link.tail;
636 vector = tail;
637 }
638 dev->irq = temp;
639
597 save_state->cap_nr = PCI_CAP_ID_MSIX; 640 save_state->cap_nr = PCI_CAP_ID_MSIX;
598 pci_add_saved_cap(dev, save_state); 641 pci_add_saved_cap(dev, save_state);
599 return 0; 642 return 0;
@@ -606,8 +649,6 @@ void pci_restore_msix_state(struct pci_dev *dev)
606 int vector, head, tail = 0; 649 int vector, head, tail = 0;
607 void __iomem *base; 650 void __iomem *base;
608 int j; 651 int j;
609 struct msg_address address;
610 struct msg_data data;
611 struct msi_desc *entry; 652 struct msi_desc *entry;
612 int temp; 653 int temp;
613 struct pci_cap_saved_state *save_state; 654 struct pci_cap_saved_state *save_state;
@@ -633,20 +674,13 @@ void pci_restore_msix_state(struct pci_dev *dev)
633 base = entry->mask_base; 674 base = entry->mask_base;
634 j = entry->msi_attrib.entry_nr; 675 j = entry->msi_attrib.entry_nr;
635 676
636 msi_address_init(&address); 677 writel(entry->address_lo_save,
637 msi_data_init(&data, vector);
638
639 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
640 address.lo_address.value |= entry->msi_attrib.current_cpu <<
641 MSI_TARGET_CPU_SHIFT;
642
643 writel(address.lo_address.value,
644 base + j * PCI_MSIX_ENTRY_SIZE + 678 base + j * PCI_MSIX_ENTRY_SIZE +
645 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); 679 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
646 writel(address.hi_address, 680 writel(entry->address_hi_save,
647 base + j * PCI_MSIX_ENTRY_SIZE + 681 base + j * PCI_MSIX_ENTRY_SIZE +
648 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); 682 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
649 writel(*(u32*)&data, 683 writel(entry->data_save,
650 base + j * PCI_MSIX_ENTRY_SIZE + 684 base + j * PCI_MSIX_ENTRY_SIZE +
651 PCI_MSIX_ENTRY_DATA_OFFSET); 685 PCI_MSIX_ENTRY_DATA_OFFSET);
652 686
@@ -660,30 +694,32 @@ void pci_restore_msix_state(struct pci_dev *dev)
660} 694}
661#endif 695#endif
662 696
663static void msi_register_init(struct pci_dev *dev, struct msi_desc *entry) 697static int msi_register_init(struct pci_dev *dev, struct msi_desc *entry)
664{ 698{
665 struct msg_address address; 699 int status;
666 struct msg_data data; 700 u32 address_hi;
701 u32 address_lo;
702 u32 data;
667 int pos, vector = dev->irq; 703 int pos, vector = dev->irq;
668 u16 control; 704 u16 control;
669 705
670 pos = pci_find_capability(dev, PCI_CAP_ID_MSI); 706 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
671 pci_read_config_word(dev, msi_control_reg(pos), &control); 707 pci_read_config_word(dev, msi_control_reg(pos), &control);
708
672 /* Configure MSI capability structure */ 709 /* Configure MSI capability structure */
673 msi_address_init(&address); 710 status = msi_ops->setup(dev, vector, &address_hi, &address_lo, &data);
674 msi_data_init(&data, vector); 711 if (status < 0)
675 entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >> 712 return status;
676 MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); 713
677 pci_write_config_dword(dev, msi_lower_address_reg(pos), 714 pci_write_config_dword(dev, msi_lower_address_reg(pos), address_lo);
678 address.lo_address.value);
679 if (is_64bit_address(control)) { 715 if (is_64bit_address(control)) {
680 pci_write_config_dword(dev, 716 pci_write_config_dword(dev,
681 msi_upper_address_reg(pos), address.hi_address); 717 msi_upper_address_reg(pos), address_hi);
682 pci_write_config_word(dev, 718 pci_write_config_word(dev,
683 msi_data_reg(pos, 1), *((u32*)&data)); 719 msi_data_reg(pos, 1), data);
684 } else 720 } else
685 pci_write_config_word(dev, 721 pci_write_config_word(dev,
686 msi_data_reg(pos, 0), *((u32*)&data)); 722 msi_data_reg(pos, 0), data);
687 if (entry->msi_attrib.maskbit) { 723 if (entry->msi_attrib.maskbit) {
688 unsigned int maskbits, temp; 724 unsigned int maskbits, temp;
689 /* All MSIs are unmasked by default, Mask them all */ 725 /* All MSIs are unmasked by default, Mask them all */
@@ -697,6 +733,8 @@ static void msi_register_init(struct pci_dev *dev, struct msi_desc *entry)
697 msi_mask_bits_reg(pos, is_64bit_address(control)), 733 msi_mask_bits_reg(pos, is_64bit_address(control)),
698 maskbits); 734 maskbits);
699 } 735 }
736
737 return 0;
700} 738}
701 739
702/** 740/**
@@ -710,6 +748,7 @@ static void msi_register_init(struct pci_dev *dev, struct msi_desc *entry)
710 **/ 748 **/
711static int msi_capability_init(struct pci_dev *dev) 749static int msi_capability_init(struct pci_dev *dev)
712{ 750{
751 int status;
713 struct msi_desc *entry; 752 struct msi_desc *entry;
714 int pos, vector; 753 int pos, vector;
715 u16 control; 754 u16 control;
@@ -742,7 +781,12 @@ static int msi_capability_init(struct pci_dev *dev)
742 /* Replace with MSI handler */ 781 /* Replace with MSI handler */
743 irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit); 782 irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit);
744 /* Configure MSI capability structure */ 783 /* Configure MSI capability structure */
745 msi_register_init(dev, entry); 784 status = msi_register_init(dev, entry);
785 if (status != 0) {
786 dev->irq = entry->msi_attrib.default_vector;
787 kmem_cache_free(msi_cachep, entry);
788 return status;
789 }
746 790
747 attach_msi_entry(entry, vector); 791 attach_msi_entry(entry, vector);
748 /* Set MSI enabled bits */ 792 /* Set MSI enabled bits */
@@ -765,8 +809,10 @@ static int msix_capability_init(struct pci_dev *dev,
765 struct msix_entry *entries, int nvec) 809 struct msix_entry *entries, int nvec)
766{ 810{
767 struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; 811 struct msi_desc *head = NULL, *tail = NULL, *entry = NULL;
768 struct msg_address address; 812 u32 address_hi;
769 struct msg_data data; 813 u32 address_lo;
814 u32 data;
815 int status;
770 int vector, pos, i, j, nr_entries, temp = 0; 816 int vector, pos, i, j, nr_entries, temp = 0;
771 unsigned long phys_addr; 817 unsigned long phys_addr;
772 u32 table_offset; 818 u32 table_offset;
@@ -822,18 +868,20 @@ static int msix_capability_init(struct pci_dev *dev,
822 /* Replace with MSI-X handler */ 868 /* Replace with MSI-X handler */
823 irq_handler_init(PCI_CAP_ID_MSIX, vector, 1); 869 irq_handler_init(PCI_CAP_ID_MSIX, vector, 1);
824 /* Configure MSI-X capability structure */ 870 /* Configure MSI-X capability structure */
825 msi_address_init(&address); 871 status = msi_ops->setup(dev, vector,
826 msi_data_init(&data, vector); 872 &address_hi,
827 entry->msi_attrib.current_cpu = 873 &address_lo,
828 ((address.lo_address.u.dest_id >> 874 &data);
829 MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); 875 if (status < 0)
830 writel(address.lo_address.value, 876 break;
877
878 writel(address_lo,
831 base + j * PCI_MSIX_ENTRY_SIZE + 879 base + j * PCI_MSIX_ENTRY_SIZE +
832 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); 880 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
833 writel(address.hi_address, 881 writel(address_hi,
834 base + j * PCI_MSIX_ENTRY_SIZE + 882 base + j * PCI_MSIX_ENTRY_SIZE +
835 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); 883 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
836 writel(*(u32*)&data, 884 writel(data,
837 base + j * PCI_MSIX_ENTRY_SIZE + 885 base + j * PCI_MSIX_ENTRY_SIZE +
838 PCI_MSIX_ENTRY_DATA_OFFSET); 886 PCI_MSIX_ENTRY_DATA_OFFSET);
839 attach_msi_entry(entry, vector); 887 attach_msi_entry(entry, vector);
@@ -865,6 +913,7 @@ static int msix_capability_init(struct pci_dev *dev,
865 **/ 913 **/
866int pci_enable_msi(struct pci_dev* dev) 914int pci_enable_msi(struct pci_dev* dev)
867{ 915{
916 struct pci_bus *bus;
868 int pos, temp, status = -EINVAL; 917 int pos, temp, status = -EINVAL;
869 u16 control; 918 u16 control;
870 919
@@ -874,8 +923,9 @@ int pci_enable_msi(struct pci_dev* dev)
874 if (dev->no_msi) 923 if (dev->no_msi)
875 return status; 924 return status;
876 925
877 if (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) 926 for (bus = dev->bus; bus; bus = bus->parent)
878 return -EINVAL; 927 if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
928 return -EINVAL;
879 929
880 temp = dev->irq; 930 temp = dev->irq;
881 931
@@ -887,23 +937,23 @@ int pci_enable_msi(struct pci_dev* dev)
887 if (!pos) 937 if (!pos)
888 return -EINVAL; 938 return -EINVAL;
889 939
890 pci_read_config_word(dev, msi_control_reg(pos), &control);
891 if (control & PCI_MSI_FLAGS_ENABLE)
892 return 0; /* Already in MSI mode */
893
894 if (!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { 940 if (!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
895 /* Lookup Sucess */ 941 /* Lookup Sucess */
896 unsigned long flags; 942 unsigned long flags;
897 943
944 pci_read_config_word(dev, msi_control_reg(pos), &control);
945 if (control & PCI_MSI_FLAGS_ENABLE)
946 return 0; /* Already in MSI mode */
898 spin_lock_irqsave(&msi_lock, flags); 947 spin_lock_irqsave(&msi_lock, flags);
899 if (!vector_irq[dev->irq]) { 948 if (!vector_irq[dev->irq]) {
900 msi_desc[dev->irq]->msi_attrib.state = 0; 949 msi_desc[dev->irq]->msi_attrib.state = 0;
901 vector_irq[dev->irq] = -1; 950 vector_irq[dev->irq] = -1;
902 nr_released_vectors--; 951 nr_released_vectors--;
903 spin_unlock_irqrestore(&msi_lock, flags); 952 spin_unlock_irqrestore(&msi_lock, flags);
904 msi_register_init(dev, msi_desc[dev->irq]); 953 status = msi_register_init(dev, msi_desc[dev->irq]);
905 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); 954 if (status == 0)
906 return 0; 955 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
956 return status;
907 } 957 }
908 spin_unlock_irqrestore(&msi_lock, flags); 958 spin_unlock_irqrestore(&msi_lock, flags);
909 dev->irq = temp; 959 dev->irq = temp;
@@ -980,6 +1030,8 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
980 void __iomem *base; 1030 void __iomem *base;
981 unsigned long flags; 1031 unsigned long flags;
982 1032
1033 msi_ops->teardown(vector);
1034
983 spin_lock_irqsave(&msi_lock, flags); 1035 spin_lock_irqsave(&msi_lock, flags);
984 entry = msi_desc[vector]; 1036 entry = msi_desc[vector];
985 if (!entry || entry->dev != dev) { 1037 if (!entry || entry->dev != dev) {
@@ -1008,33 +1060,8 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
1008 entry_nr * PCI_MSIX_ENTRY_SIZE + 1060 entry_nr * PCI_MSIX_ENTRY_SIZE +
1009 PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); 1061 PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
1010 1062
1011 if (head == vector) { 1063 if (head == vector)
1012 /*
1013 * Detect last MSI-X vector to be released.
1014 * Release the MSI-X memory-mapped table.
1015 */
1016#if 0
1017 int pos, nr_entries;
1018 unsigned long phys_addr;
1019 u32 table_offset;
1020 u16 control;
1021 u8 bir;
1022
1023 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
1024 pci_read_config_word(dev, msi_control_reg(pos),
1025 &control);
1026 nr_entries = multi_msix_capable(control);
1027 pci_read_config_dword(dev, msix_table_offset_reg(pos),
1028 &table_offset);
1029 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
1030 table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
1031 phys_addr = pci_resource_start(dev, bir) + table_offset;
1032/*
1033 * FIXME! and what did you want to do with phys_addr?
1034 */
1035#endif
1036 iounmap(base); 1064 iounmap(base);
1037 }
1038 } 1065 }
1039 1066
1040 return 0; 1067 return 0;
@@ -1108,6 +1135,7 @@ static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec)
1108 **/ 1135 **/
1109int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) 1136int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
1110{ 1137{
1138 struct pci_bus *bus;
1111 int status, pos, nr_entries, free_vectors; 1139 int status, pos, nr_entries, free_vectors;
1112 int i, j, temp; 1140 int i, j, temp;
1113 u16 control; 1141 u16 control;
@@ -1116,6 +1144,13 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
1116 if (!pci_msi_enable || !dev || !entries) 1144 if (!pci_msi_enable || !dev || !entries)
1117 return -EINVAL; 1145 return -EINVAL;
1118 1146
1147 if (dev->no_msi)
1148 return -EINVAL;
1149
1150 for (bus = dev->bus; bus; bus = bus->parent)
1151 if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
1152 return -EINVAL;
1153
1119 status = msi_init(); 1154 status = msi_init();
1120 if (status < 0) 1155 if (status < 0)
1121 return status; 1156 return status;
@@ -1300,24 +1335,6 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
1300 } 1335 }
1301 msi_free_vector(dev, vector, 0); 1336 msi_free_vector(dev, vector, 0);
1302 if (warning) { 1337 if (warning) {
1303 /* Force to release the MSI-X memory-mapped table */
1304#if 0
1305 unsigned long phys_addr;
1306 u32 table_offset;
1307 u16 control;
1308 u8 bir;
1309
1310 pci_read_config_word(dev, msi_control_reg(pos),
1311 &control);
1312 pci_read_config_dword(dev, msix_table_offset_reg(pos),
1313 &table_offset);
1314 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
1315 table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
1316 phys_addr = pci_resource_start(dev, bir) + table_offset;
1317/*
1318 * FIXME! and what did you want to do with phys_addr?
1319 */
1320#endif
1321 iounmap(base); 1338 iounmap(base);
1322 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " 1339 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
1323 "called without free_irq() on all MSI-X vectors\n", 1340 "called without free_irq() on all MSI-X vectors\n",
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
index 4ac52d441e47..56951c39d3a3 100644
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -6,6 +6,68 @@
6#ifndef MSI_H 6#ifndef MSI_H
7#define MSI_H 7#define MSI_H
8 8
9/*
10 * MSI operation vector. Used by the msi core code (drivers/pci/msi.c)
11 * to abstract platform-specific tasks relating to MSI address generation
12 * and resource management.
13 */
14struct msi_ops {
15 /**
16 * setup - generate an MSI bus address and data for a given vector
17 * @pdev: PCI device context (in)
18 * @vector: vector allocated by the msi core (in)
19 * @addr_hi: upper 32 bits of PCI bus MSI address (out)
20 * @addr_lo: lower 32 bits of PCI bus MSI address (out)
21 * @data: MSI data payload (out)
22 *
23 * Description: The setup op is used to generate a PCI bus addres and
24 * data which the msi core will program into the card MSI capability
25 * registers. The setup routine is responsible for picking an initial
26 * cpu to target the MSI at. The setup routine is responsible for
27 * examining pdev to determine the MSI capabilities of the card and
28 * generating a suitable address/data. The setup routine is
29 * responsible for allocating and tracking any system resources it
30 * needs to route the MSI to the cpu it picks, and for associating
31 * those resources with the passed in vector.
32 *
33 * Returns 0 if the MSI address/data was successfully setup.
34 **/
35
36 int (*setup) (struct pci_dev *pdev, unsigned int vector,
37 u32 *addr_hi, u32 *addr_lo, u32 *data);
38
39 /**
40 * teardown - release resources allocated by setup
41 * @vector: vector context for resources (in)
42 *
43 * Description: The teardown op is used to release any resources
44 * that were allocated in the setup routine associated with the passed
45 * in vector.
46 **/
47
48 void (*teardown) (unsigned int vector);
49
50 /**
51 * target - retarget an MSI at a different cpu
52 * @vector: vector context for resources (in)
53 * @cpu: new cpu to direct vector at (in)
54 * @addr_hi: new value of PCI bus upper 32 bits (in/out)
55 * @addr_lo: new value of PCI bus lower 32 bits (in/out)
56 *
57 * Description: The target op is used to redirect an MSI vector
58 * at a different cpu. addr_hi/addr_lo coming in are the existing
59 * values that the MSI core has programmed into the card. The
60 * target code is responsible for freeing any resources (if any)
61 * associated with the old address, and generating a new PCI bus
62 * addr_hi/addr_lo that will redirect the vector at the indicated cpu.
63 **/
64
65 void (*target) (unsigned int vector, unsigned int cpu,
66 u32 *addr_hi, u32 *addr_lo);
67};
68
69extern int msi_register(struct msi_ops *ops);
70
9#include <asm/msi.h> 71#include <asm/msi.h>
10 72
11/* 73/*
@@ -63,67 +125,6 @@ extern int pci_vector_resources(int last, int nr_released);
63#define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK) 125#define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK)
64#define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK) 126#define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK)
65 127
66/*
67 * MSI Defined Data Structures
68 */
69#define MSI_ADDRESS_HEADER 0xfee
70#define MSI_ADDRESS_HEADER_SHIFT 12
71#define MSI_ADDRESS_HEADER_MASK 0xfff000
72#define MSI_ADDRESS_DEST_ID_MASK 0xfff0000f
73#define MSI_TARGET_CPU_MASK 0xff
74#define MSI_DELIVERY_MODE 0
75#define MSI_LEVEL_MODE 1 /* Edge always assert */
76#define MSI_TRIGGER_MODE 0 /* MSI is edge sensitive */
77#define MSI_PHYSICAL_MODE 0
78#define MSI_LOGICAL_MODE 1
79#define MSI_REDIRECTION_HINT_MODE 0
80
81struct msg_data {
82#if defined(__LITTLE_ENDIAN_BITFIELD)
83 __u32 vector : 8;
84 __u32 delivery_mode : 3; /* 000b: FIXED | 001b: lowest prior */
85 __u32 reserved_1 : 3;
86 __u32 level : 1; /* 0: deassert | 1: assert */
87 __u32 trigger : 1; /* 0: edge | 1: level */
88 __u32 reserved_2 : 16;
89#elif defined(__BIG_ENDIAN_BITFIELD)
90 __u32 reserved_2 : 16;
91 __u32 trigger : 1; /* 0: edge | 1: level */
92 __u32 level : 1; /* 0: deassert | 1: assert */
93 __u32 reserved_1 : 3;
94 __u32 delivery_mode : 3; /* 000b: FIXED | 001b: lowest prior */
95 __u32 vector : 8;
96#else
97#error "Bitfield endianness not defined! Check your byteorder.h"
98#endif
99} __attribute__ ((packed));
100
101struct msg_address {
102 union {
103 struct {
104#if defined(__LITTLE_ENDIAN_BITFIELD)
105 __u32 reserved_1 : 2;
106 __u32 dest_mode : 1; /*0:physic | 1:logic */
107 __u32 redirection_hint: 1; /*0: dedicated CPU
108 1: lowest priority */
109 __u32 reserved_2 : 4;
110 __u32 dest_id : 24; /* Destination ID */
111#elif defined(__BIG_ENDIAN_BITFIELD)
112 __u32 dest_id : 24; /* Destination ID */
113 __u32 reserved_2 : 4;
114 __u32 redirection_hint: 1; /*0: dedicated CPU
115 1: lowest priority */
116 __u32 dest_mode : 1; /*0:physic | 1:logic */
117 __u32 reserved_1 : 2;
118#else
119#error "Bitfield endianness not defined! Check your byteorder.h"
120#endif
121 }u;
122 __u32 value;
123 }lo_address;
124 __u32 hi_address;
125} __attribute__ ((packed));
126
127struct msi_desc { 128struct msi_desc {
128 struct { 129 struct {
129 __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */ 130 __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */
@@ -132,7 +133,7 @@ struct msi_desc {
132 __u8 reserved: 1; /* reserved */ 133 __u8 reserved: 1; /* reserved */
133 __u8 entry_nr; /* specific enabled entry */ 134 __u8 entry_nr; /* specific enabled entry */
134 __u8 default_vector; /* default pre-assigned vector */ 135 __u8 default_vector; /* default pre-assigned vector */
135 __u8 current_cpu; /* current destination cpu */ 136 __u8 unused; /* formerly unused destination cpu*/
136 }msi_attrib; 137 }msi_attrib;
137 138
138 struct { 139 struct {
@@ -142,6 +143,14 @@ struct msi_desc {
142 143
143 void __iomem *mask_base; 144 void __iomem *mask_base;
144 struct pci_dev *dev; 145 struct pci_dev *dev;
146
147#ifdef CONFIG_PM
148 /* PM save area for MSIX address/data */
149
150 u32 address_hi_save;
151 u32 address_lo_save;
152 u32 data_save;
153#endif
145}; 154};
146 155
147#endif /* MSI_H */ 156#endif /* MSI_H */
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index c2ecae5ff0c1..bb7456c1dbac 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -267,7 +267,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
267 267
268 268
269/* ACPI bus type */ 269/* ACPI bus type */
270static int pci_acpi_find_device(struct device *dev, acpi_handle *handle) 270static int acpi_pci_find_device(struct device *dev, acpi_handle *handle)
271{ 271{
272 struct pci_dev * pci_dev; 272 struct pci_dev * pci_dev;
273 acpi_integer addr; 273 acpi_integer addr;
@@ -281,7 +281,7 @@ static int pci_acpi_find_device(struct device *dev, acpi_handle *handle)
281 return 0; 281 return 0;
282} 282}
283 283
284static int pci_acpi_find_root_bridge(struct device *dev, acpi_handle *handle) 284static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle)
285{ 285{
286 int num; 286 int num;
287 unsigned int seg, bus; 287 unsigned int seg, bus;
@@ -299,21 +299,21 @@ static int pci_acpi_find_root_bridge(struct device *dev, acpi_handle *handle)
299 return 0; 299 return 0;
300} 300}
301 301
302static struct acpi_bus_type pci_acpi_bus = { 302static struct acpi_bus_type acpi_pci_bus = {
303 .bus = &pci_bus_type, 303 .bus = &pci_bus_type,
304 .find_device = pci_acpi_find_device, 304 .find_device = acpi_pci_find_device,
305 .find_bridge = pci_acpi_find_root_bridge, 305 .find_bridge = acpi_pci_find_root_bridge,
306}; 306};
307 307
308static int __init pci_acpi_init(void) 308static int __init acpi_pci_init(void)
309{ 309{
310 int ret; 310 int ret;
311 311
312 ret = register_acpi_bus_type(&pci_acpi_bus); 312 ret = register_acpi_bus_type(&acpi_pci_bus);
313 if (ret) 313 if (ret)
314 return 0; 314 return 0;
315 platform_pci_choose_state = acpi_pci_choose_state; 315 platform_pci_choose_state = acpi_pci_choose_state;
316 platform_pci_set_power_state = acpi_pci_set_power_state; 316 platform_pci_set_power_state = acpi_pci_set_power_state;
317 return 0; 317 return 0;
318} 318}
319arch_initcall(pci_acpi_init); 319arch_initcall(acpi_pci_init);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 56ac2bc003c7..bc405c035ce3 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -43,6 +43,29 @@ pci_config_attr(subsystem_vendor, "0x%04x\n");
43pci_config_attr(subsystem_device, "0x%04x\n"); 43pci_config_attr(subsystem_device, "0x%04x\n");
44pci_config_attr(class, "0x%06x\n"); 44pci_config_attr(class, "0x%06x\n");
45pci_config_attr(irq, "%u\n"); 45pci_config_attr(irq, "%u\n");
46pci_config_attr(is_enabled, "%u\n");
47
48static ssize_t broken_parity_status_show(struct device *dev,
49 struct device_attribute *attr,
50 char *buf)
51{
52 struct pci_dev *pdev = to_pci_dev(dev);
53 return sprintf (buf, "%u\n", pdev->broken_parity_status);
54}
55
56static ssize_t broken_parity_status_store(struct device *dev,
57 struct device_attribute *attr,
58 const char *buf, size_t count)
59{
60 struct pci_dev *pdev = to_pci_dev(dev);
61 ssize_t consumed = -EINVAL;
62
63 if ((count > 0) && (*buf == '0' || *buf == '1')) {
64 pdev->broken_parity_status = *buf == '1' ? 1 : 0;
65 consumed = count;
66 }
67 return consumed;
68}
46 69
47static ssize_t local_cpus_show(struct device *dev, 70static ssize_t local_cpus_show(struct device *dev,
48 struct device_attribute *attr, char *buf) 71 struct device_attribute *attr, char *buf)
@@ -90,6 +113,25 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
90 (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8), 113 (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
91 (u8)(pci_dev->class)); 114 (u8)(pci_dev->class));
92} 115}
116static ssize_t
117is_enabled_store(struct device *dev, struct device_attribute *attr,
118 const char *buf, size_t count)
119{
120 struct pci_dev *pdev = to_pci_dev(dev);
121
122 /* this can crash the machine when done on the "wrong" device */
123 if (!capable(CAP_SYS_ADMIN))
124 return count;
125
126 if (*buf == '0')
127 pci_disable_device(pdev);
128
129 if (*buf == '1')
130 pci_enable_device(pdev);
131
132 return count;
133}
134
93 135
94struct device_attribute pci_dev_attrs[] = { 136struct device_attribute pci_dev_attrs[] = {
95 __ATTR_RO(resource), 137 __ATTR_RO(resource),
@@ -101,6 +143,9 @@ struct device_attribute pci_dev_attrs[] = {
101 __ATTR_RO(irq), 143 __ATTR_RO(irq),
102 __ATTR_RO(local_cpus), 144 __ATTR_RO(local_cpus),
103 __ATTR_RO(modalias), 145 __ATTR_RO(modalias),
146 __ATTR(enable, 0600, is_enabled_show, is_enabled_store),
147 __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
148 broken_parity_status_show,broken_parity_status_store),
104 __ATTR_NULL, 149 __ATTR_NULL,
105}; 150};
106 151
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index fde41cc14734..d408a3c30426 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -517,7 +517,12 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
517int 517int
518pci_enable_device(struct pci_dev *dev) 518pci_enable_device(struct pci_dev *dev)
519{ 519{
520 int err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); 520 int err;
521
522 if (dev->is_enabled)
523 return 0;
524
525 err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
521 if (err) 526 if (err)
522 return err; 527 return err;
523 pci_fixup_device(pci_fixup_enable, dev); 528 pci_fixup_device(pci_fixup_enable, dev);
@@ -546,7 +551,14 @@ void
546pci_disable_device(struct pci_dev *dev) 551pci_disable_device(struct pci_dev *dev)
547{ 552{
548 u16 pci_command; 553 u16 pci_command;
549 554
555 if (dev->msi_enabled)
556 disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI),
557 PCI_CAP_ID_MSI);
558 if (dev->msix_enabled)
559 disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI),
560 PCI_CAP_ID_MSIX);
561
550 pci_read_config_word(dev, PCI_COMMAND, &pci_command); 562 pci_read_config_word(dev, PCI_COMMAND, &pci_command);
551 if (pci_command & PCI_COMMAND_MASTER) { 563 if (pci_command & PCI_COMMAND_MASTER) {
552 pci_command &= ~PCI_COMMAND_MASTER; 564 pci_command &= ~PCI_COMMAND_MASTER;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 30630cbe2fe3..29bdeca031a8 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -40,7 +40,7 @@ extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int
40extern void pci_remove_legacy_files(struct pci_bus *bus); 40extern void pci_remove_legacy_files(struct pci_bus *bus);
41 41
42/* Lock for read/write access to pci device and bus lists */ 42/* Lock for read/write access to pci device and bus lists */
43extern spinlock_t pci_bus_lock; 43extern struct rw_semaphore pci_bus_sem;
44 44
45#ifdef CONFIG_X86_IO_APIC 45#ifdef CONFIG_X86_IO_APIC
46extern int pci_msi_quirk; 46extern int pci_msi_quirk;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index a10ed9dab2c2..f89dbc3738b7 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -180,25 +180,31 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
180 res->flags |= pci_calc_resource_flags(l); 180 res->flags |= pci_calc_resource_flags(l);
181 if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) 181 if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
182 == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) { 182 == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) {
183 pci_read_config_dword(dev, reg+4, &l); 183 u32 szhi, lhi;
184 pci_read_config_dword(dev, reg+4, &lhi);
185 pci_write_config_dword(dev, reg+4, ~0);
186 pci_read_config_dword(dev, reg+4, &szhi);
187 pci_write_config_dword(dev, reg+4, lhi);
188 szhi = pci_size(lhi, szhi, 0xffffffff);
184 next++; 189 next++;
185#if BITS_PER_LONG == 64 190#if BITS_PER_LONG == 64
186 res->start |= ((unsigned long) l) << 32; 191 res->start |= ((unsigned long) lhi) << 32;
187 res->end = res->start + sz; 192 res->end = res->start + sz;
188 pci_write_config_dword(dev, reg+4, ~0); 193 if (szhi) {
189 pci_read_config_dword(dev, reg+4, &sz);
190 pci_write_config_dword(dev, reg+4, l);
191 sz = pci_size(l, sz, 0xffffffff);
192 if (sz) {
193 /* This BAR needs > 4GB? Wow. */ 194 /* This BAR needs > 4GB? Wow. */
194 res->end |= (unsigned long)sz<<32; 195 res->end |= (unsigned long)szhi<<32;
195 } 196 }
196#else 197#else
197 if (l) { 198 if (szhi) {
198 printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", pci_name(dev)); 199 printk(KERN_ERR "PCI: Unable to handle 64-bit BAR for device %s\n", pci_name(dev));
199 res->start = 0; 200 res->start = 0;
200 res->flags = 0; 201 res->flags = 0;
201 continue; 202 } else if (lhi) {
203 /* 64-bit wide address, treat as disabled */
204 pci_write_config_dword(dev, reg, l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK);
205 pci_write_config_dword(dev, reg+4, 0);
206 res->start = 0;
207 res->end = sz;
202 } 208 }
203#endif 209#endif
204 } 210 }
@@ -377,9 +383,9 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de
377 383
378 child = pci_alloc_child_bus(parent, dev, busnr); 384 child = pci_alloc_child_bus(parent, dev, busnr);
379 if (child) { 385 if (child) {
380 spin_lock(&pci_bus_lock); 386 down_write(&pci_bus_sem);
381 list_add_tail(&child->node, &parent->children); 387 list_add_tail(&child->node, &parent->children);
382 spin_unlock(&pci_bus_lock); 388 up_write(&pci_bus_sem);
383 } 389 }
384 return child; 390 return child;
385} 391}
@@ -838,9 +844,9 @@ void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
838 * and the bus list for fixup functions, etc. 844 * and the bus list for fixup functions, etc.
839 */ 845 */
840 INIT_LIST_HEAD(&dev->global_list); 846 INIT_LIST_HEAD(&dev->global_list);
841 spin_lock(&pci_bus_lock); 847 down_write(&pci_bus_sem);
842 list_add_tail(&dev->bus_list, &bus->devices); 848 list_add_tail(&dev->bus_list, &bus->devices);
843 spin_unlock(&pci_bus_lock); 849 up_write(&pci_bus_sem);
844} 850}
845 851
846struct pci_dev * __devinit 852struct pci_dev * __devinit
@@ -975,9 +981,10 @@ struct pci_bus * __devinit pci_create_bus(struct device *parent,
975 pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); 981 pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
976 goto err_out; 982 goto err_out;
977 } 983 }
978 spin_lock(&pci_bus_lock); 984
985 down_write(&pci_bus_sem);
979 list_add_tail(&b->node, &pci_root_buses); 986 list_add_tail(&b->node, &pci_root_buses);
980 spin_unlock(&pci_bus_lock); 987 up_write(&pci_bus_sem);
981 988
982 memset(dev, 0, sizeof(*dev)); 989 memset(dev, 0, sizeof(*dev));
983 dev->parent = parent; 990 dev->parent = parent;
@@ -1017,9 +1024,9 @@ class_dev_create_file_err:
1017class_dev_reg_err: 1024class_dev_reg_err:
1018 device_unregister(dev); 1025 device_unregister(dev);
1019dev_reg_err: 1026dev_reg_err:
1020 spin_lock(&pci_bus_lock); 1027 down_write(&pci_bus_sem);
1021 list_del(&b->node); 1028 list_del(&b->node);
1022 spin_unlock(&pci_bus_lock); 1029 up_write(&pci_bus_sem);
1023err_out: 1030err_out:
1024 kfree(dev); 1031 kfree(dev);
1025 kfree(b); 1032 kfree(b);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index d378478612fb..4364d793f73b 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -24,6 +24,17 @@
24#include <linux/acpi.h> 24#include <linux/acpi.h>
25#include "pci.h" 25#include "pci.h"
26 26
27/* The Mellanox Tavor device gives false positive parity errors
28 * Mark this device with a broken_parity_status, to allow
29 * PCI scanning code to "skip" this now blacklisted device.
30 */
31static void __devinit quirk_mellanox_tavor(struct pci_dev *dev)
32{
33 dev->broken_parity_status = 1; /* This device gives false positives */
34}
35DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR,quirk_mellanox_tavor);
36DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE,quirk_mellanox_tavor);
37
27/* Deal with broken BIOS'es that neglect to enable passive release, 38/* Deal with broken BIOS'es that neglect to enable passive release,
28 which can cause problems in combination with the 82441FX/PPro MTRRs */ 39 which can cause problems in combination with the 82441FX/PPro MTRRs */
29static void __devinit quirk_passive_release(struct pci_dev *dev) 40static void __devinit quirk_passive_release(struct pci_dev *dev)
@@ -878,27 +889,30 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_e
878 * when a PCI-Soundcard is added. The BIOS only gives Options 889 * when a PCI-Soundcard is added. The BIOS only gives Options
879 * "Disabled" and "AUTO". This Quirk Sets the corresponding 890 * "Disabled" and "AUTO". This Quirk Sets the corresponding
880 * Register-Value to enable the Soundcard. 891 * Register-Value to enable the Soundcard.
892 *
893 * FIXME: Presently this quirk will run on anything that has an 8237
894 * which isn't correct, we need to check DMI tables or something in
895 * order to make sure it only runs on the MSI-K8T-Neo2Fir. Because it
896 * runs everywhere at present we suppress the printk output in most
897 * irrelevant cases.
881 */ 898 */
882static void __init k8t_sound_hostbridge(struct pci_dev *dev) 899static void __init k8t_sound_hostbridge(struct pci_dev *dev)
883{ 900{
884 unsigned char val; 901 unsigned char val;
885 902
886 printk(KERN_INFO "PCI: Quirk-MSI-K8T Soundcard On\n");
887 pci_read_config_byte(dev, 0x50, &val); 903 pci_read_config_byte(dev, 0x50, &val);
888 if (val == 0x88 || val == 0xc8) { 904 if (val == 0x88 || val == 0xc8) {
905 /* Assume it's probably a MSI-K8T-Neo2Fir */
906 printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, attempting to turn soundcard ON\n");
889 pci_write_config_byte(dev, 0x50, val & (~0x40)); 907 pci_write_config_byte(dev, 0x50, val & (~0x40));
890 908
891 /* Verify the Change for Status output */ 909 /* Verify the Change for Status output */
892 pci_read_config_byte(dev, 0x50, &val); 910 pci_read_config_byte(dev, 0x50, &val);
893 if (val & 0x40) 911 if (val & 0x40)
894 printk(KERN_INFO "PCI: MSI-K8T soundcard still off\n"); 912 printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, soundcard still off\n");
895 else 913 else
896 printk(KERN_INFO "PCI: MSI-K8T soundcard on\n"); 914 printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, soundcard on\n");
897 } else {
898 printk(KERN_INFO "PCI: Unexpected Value in PCI-Register: "
899 "no Change!\n");
900 } 915 }
901
902} 916}
903DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); 917DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge);
904 918
@@ -1485,6 +1499,25 @@ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
1485} 1499}
1486DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io); 1500DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io);
1487 1501
1502/* Under some circumstances, AER is not linked with extended capabilities.
1503 * Force it to be linked by setting the corresponding control bit in the
1504 * config space.
1505 */
1506static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
1507{
1508 uint8_t b;
1509 if (pci_read_config_byte(dev, 0xf41, &b) == 0) {
1510 if (!(b & 0x20)) {
1511 pci_write_config_byte(dev, 0xf41, b | 0x20);
1512 printk(KERN_INFO
1513 "PCI: Linking AER extended capability on %s\n",
1514 pci_name(dev));
1515 }
1516 }
1517}
1518DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
1519 quirk_nvidia_ck804_pcie_aer_ext_cap);
1520
1488EXPORT_SYMBOL(pcie_mch_quirk); 1521EXPORT_SYMBOL(pcie_mch_quirk);
1489#ifdef CONFIG_HOTPLUG 1522#ifdef CONFIG_HOTPLUG
1490EXPORT_SYMBOL(pci_fixup_device); 1523EXPORT_SYMBOL(pci_fixup_device);
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 1a6bf9de166f..99ffbd478b29 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -22,18 +22,18 @@ static void pci_destroy_dev(struct pci_dev *dev)
22 pci_proc_detach_device(dev); 22 pci_proc_detach_device(dev);
23 pci_remove_sysfs_dev_files(dev); 23 pci_remove_sysfs_dev_files(dev);
24 device_unregister(&dev->dev); 24 device_unregister(&dev->dev);
25 spin_lock(&pci_bus_lock); 25 down_write(&pci_bus_sem);
26 list_del(&dev->global_list); 26 list_del(&dev->global_list);
27 dev->global_list.next = dev->global_list.prev = NULL; 27 dev->global_list.next = dev->global_list.prev = NULL;
28 spin_unlock(&pci_bus_lock); 28 up_write(&pci_bus_sem);
29 } 29 }
30 30
31 /* Remove the device from the device lists, and prevent any further 31 /* Remove the device from the device lists, and prevent any further
32 * list accesses from this device */ 32 * list accesses from this device */
33 spin_lock(&pci_bus_lock); 33 down_write(&pci_bus_sem);
34 list_del(&dev->bus_list); 34 list_del(&dev->bus_list);
35 dev->bus_list.next = dev->bus_list.prev = NULL; 35 dev->bus_list.next = dev->bus_list.prev = NULL;
36 spin_unlock(&pci_bus_lock); 36 up_write(&pci_bus_sem);
37 37
38 pci_free_resources(dev); 38 pci_free_resources(dev);
39 pci_dev_put(dev); 39 pci_dev_put(dev);
@@ -62,9 +62,9 @@ void pci_remove_bus(struct pci_bus *pci_bus)
62{ 62{
63 pci_proc_detach_bus(pci_bus); 63 pci_proc_detach_bus(pci_bus);
64 64
65 spin_lock(&pci_bus_lock); 65 down_write(&pci_bus_sem);
66 list_del(&pci_bus->node); 66 list_del(&pci_bus->node);
67 spin_unlock(&pci_bus_lock); 67 up_write(&pci_bus_sem);
68 pci_remove_legacy_files(pci_bus); 68 pci_remove_legacy_files(pci_bus);
69 class_device_remove_file(&pci_bus->class_dev, 69 class_device_remove_file(&pci_bus->class_dev,
70 &class_device_attr_cpuaffinity); 70 &class_device_attr_cpuaffinity);
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index ce7dd6e7be60..622b3f8ba820 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -13,7 +13,7 @@
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14#include "pci.h" 14#include "pci.h"
15 15
16DEFINE_SPINLOCK(pci_bus_lock); 16DECLARE_RWSEM(pci_bus_sem);
17 17
18static struct pci_bus * __devinit 18static struct pci_bus * __devinit
19pci_do_find_bus(struct pci_bus* bus, unsigned char busnr) 19pci_do_find_bus(struct pci_bus* bus, unsigned char busnr)
@@ -72,11 +72,11 @@ pci_find_next_bus(const struct pci_bus *from)
72 struct pci_bus *b = NULL; 72 struct pci_bus *b = NULL;
73 73
74 WARN_ON(in_interrupt()); 74 WARN_ON(in_interrupt());
75 spin_lock(&pci_bus_lock); 75 down_read(&pci_bus_sem);
76 n = from ? from->node.next : pci_root_buses.next; 76 n = from ? from->node.next : pci_root_buses.next;
77 if (n != &pci_root_buses) 77 if (n != &pci_root_buses)
78 b = pci_bus_b(n); 78 b = pci_bus_b(n);
79 spin_unlock(&pci_bus_lock); 79 up_read(&pci_bus_sem);
80 return b; 80 return b;
81} 81}
82 82
@@ -124,7 +124,7 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn)
124 struct pci_dev *dev; 124 struct pci_dev *dev;
125 125
126 WARN_ON(in_interrupt()); 126 WARN_ON(in_interrupt());
127 spin_lock(&pci_bus_lock); 127 down_read(&pci_bus_sem);
128 128
129 list_for_each(tmp, &bus->devices) { 129 list_for_each(tmp, &bus->devices) {
130 dev = pci_dev_b(tmp); 130 dev = pci_dev_b(tmp);
@@ -135,7 +135,7 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn)
135 dev = NULL; 135 dev = NULL;
136 out: 136 out:
137 pci_dev_get(dev); 137 pci_dev_get(dev);
138 spin_unlock(&pci_bus_lock); 138 up_read(&pci_bus_sem);
139 return dev; 139 return dev;
140} 140}
141 141
@@ -167,7 +167,7 @@ static struct pci_dev * pci_find_subsys(unsigned int vendor,
167 struct pci_dev *dev; 167 struct pci_dev *dev;
168 168
169 WARN_ON(in_interrupt()); 169 WARN_ON(in_interrupt());
170 spin_lock(&pci_bus_lock); 170 down_read(&pci_bus_sem);
171 n = from ? from->global_list.next : pci_devices.next; 171 n = from ? from->global_list.next : pci_devices.next;
172 172
173 while (n && (n != &pci_devices)) { 173 while (n && (n != &pci_devices)) {
@@ -181,7 +181,7 @@ static struct pci_dev * pci_find_subsys(unsigned int vendor,
181 } 181 }
182 dev = NULL; 182 dev = NULL;
183exit: 183exit:
184 spin_unlock(&pci_bus_lock); 184 up_read(&pci_bus_sem);
185 return dev; 185 return dev;
186} 186}
187 187
@@ -232,7 +232,7 @@ pci_get_subsys(unsigned int vendor, unsigned int device,
232 struct pci_dev *dev; 232 struct pci_dev *dev;
233 233
234 WARN_ON(in_interrupt()); 234 WARN_ON(in_interrupt());
235 spin_lock(&pci_bus_lock); 235 down_read(&pci_bus_sem);
236 n = from ? from->global_list.next : pci_devices.next; 236 n = from ? from->global_list.next : pci_devices.next;
237 237
238 while (n && (n != &pci_devices)) { 238 while (n && (n != &pci_devices)) {
@@ -247,7 +247,7 @@ pci_get_subsys(unsigned int vendor, unsigned int device,
247 dev = NULL; 247 dev = NULL;
248exit: 248exit:
249 dev = pci_dev_get(dev); 249 dev = pci_dev_get(dev);
250 spin_unlock(&pci_bus_lock); 250 up_read(&pci_bus_sem);
251 pci_dev_put(from); 251 pci_dev_put(from);
252 return dev; 252 return dev;
253} 253}
@@ -292,7 +292,7 @@ pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct p
292 struct pci_dev *dev; 292 struct pci_dev *dev;
293 293
294 WARN_ON(in_interrupt()); 294 WARN_ON(in_interrupt());
295 spin_lock(&pci_bus_lock); 295 down_read(&pci_bus_sem);
296 n = from ? from->global_list.prev : pci_devices.prev; 296 n = from ? from->global_list.prev : pci_devices.prev;
297 297
298 while (n && (n != &pci_devices)) { 298 while (n && (n != &pci_devices)) {
@@ -304,7 +304,7 @@ pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct p
304 } 304 }
305 dev = NULL; 305 dev = NULL;
306exit: 306exit:
307 spin_unlock(&pci_bus_lock); 307 up_read(&pci_bus_sem);
308 return dev; 308 return dev;
309} 309}
310 310
@@ -328,7 +328,7 @@ struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
328 struct pci_dev *dev; 328 struct pci_dev *dev;
329 329
330 WARN_ON(in_interrupt()); 330 WARN_ON(in_interrupt());
331 spin_lock(&pci_bus_lock); 331 down_read(&pci_bus_sem);
332 n = from ? from->global_list.next : pci_devices.next; 332 n = from ? from->global_list.next : pci_devices.next;
333 333
334 while (n && (n != &pci_devices)) { 334 while (n && (n != &pci_devices)) {
@@ -340,7 +340,7 @@ struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
340 dev = NULL; 340 dev = NULL;
341exit: 341exit:
342 dev = pci_dev_get(dev); 342 dev = pci_dev_get(dev);
343 spin_unlock(&pci_bus_lock); 343 up_read(&pci_bus_sem);
344 pci_dev_put(from); 344 pci_dev_put(from);
345 return dev; 345 return dev;
346} 346}
@@ -362,7 +362,7 @@ int pci_dev_present(const struct pci_device_id *ids)
362 int found = 0; 362 int found = 0;
363 363
364 WARN_ON(in_interrupt()); 364 WARN_ON(in_interrupt());
365 spin_lock(&pci_bus_lock); 365 down_read(&pci_bus_sem);
366 while (ids->vendor || ids->subvendor || ids->class_mask) { 366 while (ids->vendor || ids->subvendor || ids->class_mask) {
367 list_for_each_entry(dev, &pci_devices, global_list) { 367 list_for_each_entry(dev, &pci_devices, global_list) {
368 if (pci_match_one_device(ids, dev)) { 368 if (pci_match_one_device(ids, dev)) {
@@ -372,8 +372,8 @@ int pci_dev_present(const struct pci_device_id *ids)
372 } 372 }
373 ids++; 373 ids++;
374 } 374 }
375exit: 375exit:
376 spin_unlock(&pci_bus_lock); 376 up_read(&pci_bus_sem);
377 return found; 377 return found;
378} 378}
379EXPORT_SYMBOL(pci_dev_present); 379EXPORT_SYMBOL(pci_dev_present);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 28ce3a7ee434..35086e80faa9 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -55,9 +55,10 @@ pbus_assign_resources_sorted(struct pci_bus *bus)
55 list_for_each_entry(dev, &bus->devices, bus_list) { 55 list_for_each_entry(dev, &bus->devices, bus_list) {
56 u16 class = dev->class >> 8; 56 u16 class = dev->class >> 8;
57 57
58 /* Don't touch classless devices and host bridges. */ 58 /* Don't touch classless devices or host bridges or ioapics. */
59 if (class == PCI_CLASS_NOT_DEFINED || 59 if (class == PCI_CLASS_NOT_DEFINED ||
60 class == PCI_CLASS_BRIDGE_HOST) 60 class == PCI_CLASS_BRIDGE_HOST ||
61 class == PCI_CLASS_SYSTEM_PIC)
61 continue; 62 continue;
62 63
63 pdev_sort_resources(dev, &head); 64 pdev_sort_resources(dev, &head);
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index ea9277b7f899..577f4b55c46d 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -155,6 +155,46 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
155 return ret; 155 return ret;
156} 156}
157 157
158#ifdef CONFIG_EMBEDDED
159int pci_assign_resource_fixed(struct pci_dev *dev, int resno)
160{
161 struct pci_bus *bus = dev->bus;
162 struct resource *res = dev->resource + resno;
163 unsigned int type_mask;
164 int i, ret = -EBUSY;
165
166 type_mask = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH;
167
168 for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
169 struct resource *r = bus->resource[i];
170 if (!r)
171 continue;
172
173 /* type_mask must match */
174 if ((res->flags ^ r->flags) & type_mask)
175 continue;
176
177 ret = request_resource(r, res);
178
179 if (ret == 0)
180 break;
181 }
182
183 if (ret) {
184 printk(KERN_ERR "PCI: Failed to allocate %s resource "
185 "#%d:%llx@%llx for %s\n",
186 res->flags & IORESOURCE_IO ? "I/O" : "mem",
187 resno, (unsigned long long)(res->end - res->start + 1),
188 (unsigned long long)res->start, pci_name(dev));
189 } else if (resno < PCI_BRIDGE_RESOURCES) {
190 pci_update_resource(dev, res, resno);
191 }
192
193 return ret;
194}
195EXPORT_SYMBOL_GPL(pci_assign_resource_fixed);
196#endif
197
158/* Sort resources by alignment */ 198/* Sort resources by alignment */
159void __devinit 199void __devinit
160pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) 200pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 77bb2351500c..680f6063954b 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -397,30 +397,6 @@
397#include "ql1280_fw.h" 397#include "ql1280_fw.h"
398#include "ql1040_fw.h" 398#include "ql1040_fw.h"
399 399
400
401/*
402 * Missing PCI ID's
403 */
404#ifndef PCI_DEVICE_ID_QLOGIC_ISP1080
405#define PCI_DEVICE_ID_QLOGIC_ISP1080 0x1080
406#endif
407#ifndef PCI_DEVICE_ID_QLOGIC_ISP1240
408#define PCI_DEVICE_ID_QLOGIC_ISP1240 0x1240
409#endif
410#ifndef PCI_DEVICE_ID_QLOGIC_ISP1280
411#define PCI_DEVICE_ID_QLOGIC_ISP1280 0x1280
412#endif
413#ifndef PCI_DEVICE_ID_QLOGIC_ISP10160
414#define PCI_DEVICE_ID_QLOGIC_ISP10160 0x1016
415#endif
416#ifndef PCI_DEVICE_ID_QLOGIC_ISP12160
417#define PCI_DEVICE_ID_QLOGIC_ISP12160 0x1216
418#endif
419
420#ifndef PCI_VENDOR_ID_AMI
421#define PCI_VENDOR_ID_AMI 0x101e
422#endif
423
424#ifndef BITS_PER_LONG 400#ifndef BITS_PER_LONG
425#error "BITS_PER_LONG not defined!" 401#error "BITS_PER_LONG not defined!"
426#endif 402#endif
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index 8a29ce340b47..27d658704cf9 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -433,13 +433,14 @@ err_out:
433 433
434 434
435/* 435/*
436 * 0x1725/0x7174 is the Vitesse VSC-7174 436 * Intel 31244 is supposed to be identical.
437 * 0x8086/0x3200 is the Intel 31244, which is supposed to be identical 437 * Compatibility is untested as of yet.
438 * compatibility is untested as of yet
439 */ 438 */
440static const struct pci_device_id vsc_sata_pci_tbl[] = { 439static const struct pci_device_id vsc_sata_pci_tbl[] = {
441 { 0x1725, 0x7174, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, 440 { PCI_VENDOR_ID_VITESSE, PCI_DEVICE_ID_VITESSE_VSC7174,
442 { 0x8086, 0x3200, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, 441 PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 },
442 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GD31244,
443 PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 },
443 { } 444 { }
444}; 445};
445 446
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index 989e4d49e5bb..7f939d066a5a 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -313,8 +313,8 @@ static const char __init *mdacon_startup(void)
313 mda_num_columns = 80; 313 mda_num_columns = 80;
314 mda_num_lines = 25; 314 mda_num_lines = 25;
315 315
316 mda_vram_base = VGA_MAP_MEM(0xb0000);
317 mda_vram_len = 0x01000; 316 mda_vram_len = 0x01000;
317 mda_vram_base = VGA_MAP_MEM(0xb0000, mda_vram_len);
318 318
319 mda_index_port = 0x3b4; 319 mda_index_port = 0x3b4;
320 mda_value_port = 0x3b5; 320 mda_value_port = 0x3b5;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index d5a04b68c4d4..e64d42e2449e 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -391,7 +391,7 @@ static const char __init *vgacon_startup(void)
391 static struct resource ega_console_resource = 391 static struct resource ega_console_resource =
392 { "ega", 0x3B0, 0x3BF }; 392 { "ega", 0x3B0, 0x3BF };
393 vga_video_type = VIDEO_TYPE_EGAM; 393 vga_video_type = VIDEO_TYPE_EGAM;
394 vga_vram_end = 0xb8000; 394 vga_vram_size = 0x8000;
395 display_desc = "EGA+"; 395 display_desc = "EGA+";
396 request_resource(&ioport_resource, 396 request_resource(&ioport_resource,
397 &ega_console_resource); 397 &ega_console_resource);
@@ -401,7 +401,7 @@ static const char __init *vgacon_startup(void)
401 static struct resource mda2_console_resource = 401 static struct resource mda2_console_resource =
402 { "mda", 0x3BF, 0x3BF }; 402 { "mda", 0x3BF, 0x3BF };
403 vga_video_type = VIDEO_TYPE_MDA; 403 vga_video_type = VIDEO_TYPE_MDA;
404 vga_vram_end = 0xb2000; 404 vga_vram_size = 0x2000;
405 display_desc = "*MDA"; 405 display_desc = "*MDA";
406 request_resource(&ioport_resource, 406 request_resource(&ioport_resource,
407 &mda1_console_resource); 407 &mda1_console_resource);
@@ -418,7 +418,7 @@ static const char __init *vgacon_startup(void)
418 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { 418 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) {
419 int i; 419 int i;
420 420
421 vga_vram_end = 0xc0000; 421 vga_vram_size = 0x8000;
422 422
423 if (!ORIG_VIDEO_ISVGA) { 423 if (!ORIG_VIDEO_ISVGA) {
424 static struct resource ega_console_resource 424 static struct resource ega_console_resource
@@ -443,7 +443,7 @@ static const char __init *vgacon_startup(void)
443 * and COE=1 isn't necessarily a good idea) 443 * and COE=1 isn't necessarily a good idea)
444 */ 444 */
445 vga_vram_base = 0xa0000; 445 vga_vram_base = 0xa0000;
446 vga_vram_end = 0xb0000; 446 vga_vram_size = 0x10000;
447 outb_p(6, VGA_GFX_I); 447 outb_p(6, VGA_GFX_I);
448 outb_p(6, VGA_GFX_D); 448 outb_p(6, VGA_GFX_D);
449#endif 449#endif
@@ -475,7 +475,7 @@ static const char __init *vgacon_startup(void)
475 static struct resource cga_console_resource = 475 static struct resource cga_console_resource =
476 { "cga", 0x3D4, 0x3D5 }; 476 { "cga", 0x3D4, 0x3D5 };
477 vga_video_type = VIDEO_TYPE_CGA; 477 vga_video_type = VIDEO_TYPE_CGA;
478 vga_vram_end = 0xba000; 478 vga_vram_size = 0x2000;
479 display_desc = "*CGA"; 479 display_desc = "*CGA";
480 request_resource(&ioport_resource, 480 request_resource(&ioport_resource,
481 &cga_console_resource); 481 &cga_console_resource);
@@ -483,9 +483,8 @@ static const char __init *vgacon_startup(void)
483 } 483 }
484 } 484 }
485 485
486 vga_vram_base = VGA_MAP_MEM(vga_vram_base); 486 vga_vram_base = VGA_MAP_MEM(vga_vram_base, vga_vram_size);
487 vga_vram_end = VGA_MAP_MEM(vga_vram_end); 487 vga_vram_end = vga_vram_base + vga_vram_size;
488 vga_vram_size = vga_vram_end - vga_vram_base;
489 488
490 /* 489 /*
491 * Find out if there is a graphics card present. 490 * Find out if there is a graphics card present.
@@ -1020,14 +1019,14 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
1020 char *charmap; 1019 char *charmap;
1021 1020
1022 if (vga_video_type != VIDEO_TYPE_EGAM) { 1021 if (vga_video_type != VIDEO_TYPE_EGAM) {
1023 charmap = (char *) VGA_MAP_MEM(colourmap); 1022 charmap = (char *) VGA_MAP_MEM(colourmap, 0);
1024 beg = 0x0e; 1023 beg = 0x0e;
1025#ifdef VGA_CAN_DO_64KB 1024#ifdef VGA_CAN_DO_64KB
1026 if (vga_video_type == VIDEO_TYPE_VGAC) 1025 if (vga_video_type == VIDEO_TYPE_VGAC)
1027 beg = 0x06; 1026 beg = 0x06;
1028#endif 1027#endif
1029 } else { 1028 } else {
1030 charmap = (char *) VGA_MAP_MEM(blackwmap); 1029 charmap = (char *) VGA_MAP_MEM(blackwmap, 0);
1031 beg = 0x0a; 1030 beg = 0x0a;
1032 } 1031 }
1033 1032
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index f3f16fd9f231..4fd2a272e03d 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -1351,7 +1351,7 @@ static int __init vga16fb_probe(struct device *device)
1351 } 1351 }
1352 1352
1353 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */ 1353 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
1354 info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS); 1354 info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS, 0);
1355 1355
1356 if (!info->screen_base) { 1356 if (!info->screen_base) {
1357 printk(KERN_ERR "vga16fb: unable to map device\n"); 1357 printk(KERN_ERR "vga16fb: unable to map device\n");
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 537893a16014..8a04216e8b4d 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -759,7 +759,6 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
759 759
760 /* Discard our unneeded old files struct */ 760 /* Discard our unneeded old files struct */
761 if (files) { 761 if (files) {
762 steal_locks(files);
763 put_files_struct(files); 762 put_files_struct(files);
764 files = NULL; 763 files = NULL;
765 } 764 }
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index d73d75591a39..599f36fd0f67 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -203,7 +203,6 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
203 goto _error; 203 goto _error;
204 204
205 if (files) { 205 if (files) {
206 steal_locks(files);
207 put_files_struct(files); 206 put_files_struct(files);
208 files = NULL; 207 files = NULL;
209 } 208 }
diff --git a/fs/block_dev.c b/fs/block_dev.c
index f5958f413bd1..44aaba202f78 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -414,21 +414,31 @@ EXPORT_SYMBOL(bdput);
414static struct block_device *bd_acquire(struct inode *inode) 414static struct block_device *bd_acquire(struct inode *inode)
415{ 415{
416 struct block_device *bdev; 416 struct block_device *bdev;
417
417 spin_lock(&bdev_lock); 418 spin_lock(&bdev_lock);
418 bdev = inode->i_bdev; 419 bdev = inode->i_bdev;
419 if (bdev && igrab(bdev->bd_inode)) { 420 if (bdev) {
421 atomic_inc(&bdev->bd_inode->i_count);
420 spin_unlock(&bdev_lock); 422 spin_unlock(&bdev_lock);
421 return bdev; 423 return bdev;
422 } 424 }
423 spin_unlock(&bdev_lock); 425 spin_unlock(&bdev_lock);
426
424 bdev = bdget(inode->i_rdev); 427 bdev = bdget(inode->i_rdev);
425 if (bdev) { 428 if (bdev) {
426 spin_lock(&bdev_lock); 429 spin_lock(&bdev_lock);
427 if (inode->i_bdev) 430 if (!inode->i_bdev) {
428 __bd_forget(inode); 431 /*
429 inode->i_bdev = bdev; 432 * We take an additional bd_inode->i_count for inode,
430 inode->i_mapping = bdev->bd_inode->i_mapping; 433 * and it's released in clear_inode() of inode.
431 list_add(&inode->i_devices, &bdev->bd_inodes); 434 * So, we can access it via ->i_mapping always
435 * without igrab().
436 */
437 atomic_inc(&bdev->bd_inode->i_count);
438 inode->i_bdev = bdev;
439 inode->i_mapping = bdev->bd_inode->i_mapping;
440 list_add(&inode->i_devices, &bdev->bd_inodes);
441 }
432 spin_unlock(&bdev_lock); 442 spin_unlock(&bdev_lock);
433 } 443 }
434 return bdev; 444 return bdev;
@@ -438,10 +448,18 @@ static struct block_device *bd_acquire(struct inode *inode)
438 448
439void bd_forget(struct inode *inode) 449void bd_forget(struct inode *inode)
440{ 450{
451 struct block_device *bdev = NULL;
452
441 spin_lock(&bdev_lock); 453 spin_lock(&bdev_lock);
442 if (inode->i_bdev) 454 if (inode->i_bdev) {
455 if (inode->i_sb != blockdev_superblock)
456 bdev = inode->i_bdev;
443 __bd_forget(inode); 457 __bd_forget(inode);
458 }
444 spin_unlock(&bdev_lock); 459 spin_unlock(&bdev_lock);
460
461 if (bdev)
462 iput(bdev->bd_inode);
445} 463}
446 464
447int bd_claim(struct block_device *bdev, void *holder) 465int bd_claim(struct block_device *bdev, void *holder)
diff --git a/fs/dcache.c b/fs/dcache.c
index 940d188e5d14..59dbc92c2079 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -359,12 +359,13 @@ restart:
359} 359}
360 360
361/* 361/*
362 * Throw away a dentry - free the inode, dput the parent. 362 * Throw away a dentry - free the inode, dput the parent. This requires that
363 * This requires that the LRU list has already been 363 * the LRU list has already been removed.
364 * removed. 364 *
365 * Called with dcache_lock, drops it and then regains. 365 * Called with dcache_lock, drops it and then regains.
366 * Called with dentry->d_lock held, drops it.
366 */ 367 */
367static inline void prune_one_dentry(struct dentry * dentry) 368static void prune_one_dentry(struct dentry * dentry)
368{ 369{
369 struct dentry * parent; 370 struct dentry * parent;
370 371
@@ -382,6 +383,8 @@ static inline void prune_one_dentry(struct dentry * dentry)
382/** 383/**
383 * prune_dcache - shrink the dcache 384 * prune_dcache - shrink the dcache
384 * @count: number of entries to try and free 385 * @count: number of entries to try and free
386 * @sb: if given, ignore dentries for other superblocks
387 * which are being unmounted.
385 * 388 *
386 * Shrink the dcache. This is done when we need 389 * Shrink the dcache. This is done when we need
387 * more memory, or simply when we need to unmount 390 * more memory, or simply when we need to unmount
@@ -392,16 +395,29 @@ static inline void prune_one_dentry(struct dentry * dentry)
392 * all the dentries are in use. 395 * all the dentries are in use.
393 */ 396 */
394 397
395static void prune_dcache(int count) 398static void prune_dcache(int count, struct super_block *sb)
396{ 399{
397 spin_lock(&dcache_lock); 400 spin_lock(&dcache_lock);
398 for (; count ; count--) { 401 for (; count ; count--) {
399 struct dentry *dentry; 402 struct dentry *dentry;
400 struct list_head *tmp; 403 struct list_head *tmp;
404 struct rw_semaphore *s_umount;
401 405
402 cond_resched_lock(&dcache_lock); 406 cond_resched_lock(&dcache_lock);
403 407
404 tmp = dentry_unused.prev; 408 tmp = dentry_unused.prev;
409 if (unlikely(sb)) {
410 /* Try to find a dentry for this sb, but don't try
411 * too hard, if they aren't near the tail they will
412 * be moved down again soon
413 */
414 int skip = count;
415 while (skip && tmp != &dentry_unused &&
416 list_entry(tmp, struct dentry, d_lru)->d_sb != sb) {
417 skip--;
418 tmp = tmp->prev;
419 }
420 }
405 if (tmp == &dentry_unused) 421 if (tmp == &dentry_unused)
406 break; 422 break;
407 list_del_init(tmp); 423 list_del_init(tmp);
@@ -427,7 +443,45 @@ static void prune_dcache(int count)
427 spin_unlock(&dentry->d_lock); 443 spin_unlock(&dentry->d_lock);
428 continue; 444 continue;
429 } 445 }
430 prune_one_dentry(dentry); 446 /*
447 * If the dentry is not DCACHED_REFERENCED, it is time
448 * to remove it from the dcache, provided the super block is
449 * NULL (which means we are trying to reclaim memory)
450 * or this dentry belongs to the same super block that
451 * we want to shrink.
452 */
453 /*
454 * If this dentry is for "my" filesystem, then I can prune it
455 * without taking the s_umount lock (I already hold it).
456 */
457 if (sb && dentry->d_sb == sb) {
458 prune_one_dentry(dentry);
459 continue;
460 }
461 /*
462 * ...otherwise we need to be sure this filesystem isn't being
463 * unmounted, otherwise we could race with
464 * generic_shutdown_super(), and end up holding a reference to
465 * an inode while the filesystem is unmounted.
466 * So we try to get s_umount, and make sure s_root isn't NULL.
467 * (Take a local copy of s_umount to avoid a use-after-free of
468 * `dentry').
469 */
470 s_umount = &dentry->d_sb->s_umount;
471 if (down_read_trylock(s_umount)) {
472 if (dentry->d_sb->s_root != NULL) {
473 prune_one_dentry(dentry);
474 up_read(s_umount);
475 continue;
476 }
477 up_read(s_umount);
478 }
479 spin_unlock(&dentry->d_lock);
480 /* Cannot remove the first dentry, and it isn't appropriate
481 * to move it to the head of the list, so give up, and try
482 * later
483 */
484 break;
431 } 485 }
432 spin_unlock(&dcache_lock); 486 spin_unlock(&dcache_lock);
433} 487}
@@ -630,7 +684,7 @@ void shrink_dcache_parent(struct dentry * parent)
630 int found; 684 int found;
631 685
632 while ((found = select_parent(parent)) != 0) 686 while ((found = select_parent(parent)) != 0)
633 prune_dcache(found); 687 prune_dcache(found, parent->d_sb);
634} 688}
635 689
636/** 690/**
@@ -643,9 +697,10 @@ void shrink_dcache_parent(struct dentry * parent)
643 * done under dcache_lock. 697 * done under dcache_lock.
644 * 698 *
645 */ 699 */
646void shrink_dcache_anon(struct hlist_head *head) 700void shrink_dcache_anon(struct super_block *sb)
647{ 701{
648 struct hlist_node *lp; 702 struct hlist_node *lp;
703 struct hlist_head *head = &sb->s_anon;
649 int found; 704 int found;
650 do { 705 do {
651 found = 0; 706 found = 0;
@@ -668,7 +723,7 @@ void shrink_dcache_anon(struct hlist_head *head)
668 } 723 }
669 } 724 }
670 spin_unlock(&dcache_lock); 725 spin_unlock(&dcache_lock);
671 prune_dcache(found); 726 prune_dcache(found, sb);
672 } while(found); 727 } while(found);
673} 728}
674 729
@@ -689,7 +744,7 @@ static int shrink_dcache_memory(int nr, gfp_t gfp_mask)
689 if (nr) { 744 if (nr) {
690 if (!(gfp_mask & __GFP_FS)) 745 if (!(gfp_mask & __GFP_FS))
691 return -1; 746 return -1;
692 prune_dcache(nr); 747 prune_dcache(nr, NULL);
693 } 748 }
694 return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure; 749 return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure;
695} 750}
diff --git a/fs/exec.c b/fs/exec.c
index d07858c0b7c4..0b88bf646143 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -866,7 +866,6 @@ int flush_old_exec(struct linux_binprm * bprm)
866 bprm->mm = NULL; /* We're using it now */ 866 bprm->mm = NULL; /* We're using it now */
867 867
868 /* This is the point of no return */ 868 /* This is the point of no return */
869 steal_locks(files);
870 put_files_struct(files); 869 put_files_struct(files);
871 870
872 current->sas_ss_sp = current->sas_ss_size = 0; 871 current->sas_ss_sp = current->sas_ss_size = 0;
diff --git a/fs/locks.c b/fs/locks.c
index ab61a8b54829..69435c68c1ed 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2206,63 +2206,6 @@ int lock_may_write(struct inode *inode, loff_t start, unsigned long len)
2206 2206
2207EXPORT_SYMBOL(lock_may_write); 2207EXPORT_SYMBOL(lock_may_write);
2208 2208
2209static inline void __steal_locks(struct file *file, fl_owner_t from)
2210{
2211 struct inode *inode = file->f_dentry->d_inode;
2212 struct file_lock *fl = inode->i_flock;
2213
2214 while (fl) {
2215 if (fl->fl_file == file && fl->fl_owner == from)
2216 fl->fl_owner = current->files;
2217 fl = fl->fl_next;
2218 }
2219}
2220
2221/* When getting ready for executing a binary, we make sure that current
2222 * has a files_struct on its own. Before dropping the old files_struct,
2223 * we take over ownership of all locks for all file descriptors we own.
2224 * Note that we may accidentally steal a lock for a file that a sibling
2225 * has created since the unshare_files() call.
2226 */
2227void steal_locks(fl_owner_t from)
2228{
2229 struct files_struct *files = current->files;
2230 int i, j;
2231 struct fdtable *fdt;
2232
2233 if (from == files)
2234 return;
2235
2236 lock_kernel();
2237 j = 0;
2238
2239 /*
2240 * We are not taking a ref to the file structures, so
2241 * we need to acquire ->file_lock.
2242 */
2243 spin_lock(&files->file_lock);
2244 fdt = files_fdtable(files);
2245 for (;;) {
2246 unsigned long set;
2247 i = j * __NFDBITS;
2248 if (i >= fdt->max_fdset || i >= fdt->max_fds)
2249 break;
2250 set = fdt->open_fds->fds_bits[j++];
2251 while (set) {
2252 if (set & 1) {
2253 struct file *file = fdt->fd[i];
2254 if (file)
2255 __steal_locks(file, from);
2256 }
2257 i++;
2258 set >>= 1;
2259 }
2260 }
2261 spin_unlock(&files->file_lock);
2262 unlock_kernel();
2263}
2264EXPORT_SYMBOL(steal_locks);
2265
2266static int __init filelock_init(void) 2209static int __init filelock_init(void)
2267{ 2210{
2268 filelock_cache = kmem_cache_create("file_lock_cache", 2211 filelock_cache = kmem_cache_create("file_lock_cache",
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index c63a83e8da98..36e1e136bb0c 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -1484,14 +1484,15 @@ static inline void ntfs_flush_dcache_pages(struct page **pages,
1484 unsigned nr_pages) 1484 unsigned nr_pages)
1485{ 1485{
1486 BUG_ON(!nr_pages); 1486 BUG_ON(!nr_pages);
1487 /*
1488 * Warning: Do not do the decrement at the same time as the call to
1489 * flush_dcache_page() because it is a NULL macro on i386 and hence the
1490 * decrement never happens so the loop never terminates.
1491 */
1487 do { 1492 do {
1488 /* 1493 --nr_pages;
1489 * Warning: Do not do the decrement at the same time as the
1490 * call because flush_dcache_page() is a NULL macro on i386
1491 * and hence the decrement never happens.
1492 */
1493 flush_dcache_page(pages[nr_pages]); 1494 flush_dcache_page(pages[nr_pages]);
1494 } while (--nr_pages > 0); 1495 } while (nr_pages > 0);
1495} 1496}
1496 1497
1497/** 1498/**
diff --git a/fs/super.c b/fs/super.c
index a66f66bb8049..9d5c2add7228 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -231,7 +231,7 @@ void generic_shutdown_super(struct super_block *sb)
231 if (root) { 231 if (root) {
232 sb->s_root = NULL; 232 sb->s_root = NULL;
233 shrink_dcache_parent(root); 233 shrink_dcache_parent(root);
234 shrink_dcache_anon(&sb->s_anon); 234 shrink_dcache_anon(sb);
235 dput(root); 235 dput(root);
236 fsync_super(sb); 236 fsync_super(sb);
237 lock_super(sb); 237 lock_super(sb);
diff --git a/include/asm-alpha/vga.h b/include/asm-alpha/vga.h
index 8ca4f6b2da19..ed06f59b544d 100644
--- a/include/asm-alpha/vga.h
+++ b/include/asm-alpha/vga.h
@@ -46,6 +46,6 @@ extern void scr_memcpyw(u16 *d, const u16 *s, unsigned int count);
46#define vga_readb(a) readb((u8 __iomem *)(a)) 46#define vga_readb(a) readb((u8 __iomem *)(a))
47#define vga_writeb(v,a) writeb(v, (u8 __iomem *)(a)) 47#define vga_writeb(v,a) writeb(v, (u8 __iomem *)(a))
48 48
49#define VGA_MAP_MEM(x) ((unsigned long) ioremap(x, 0)) 49#define VGA_MAP_MEM(x,s) ((unsigned long) ioremap(x, s))
50 50
51#endif 51#endif
diff --git a/include/asm-arm/vga.h b/include/asm-arm/vga.h
index 926e5ee128e9..1e0b913c3d71 100644
--- a/include/asm-arm/vga.h
+++ b/include/asm-arm/vga.h
@@ -4,7 +4,7 @@
4#include <asm/hardware.h> 4#include <asm/hardware.h>
5#include <asm/io.h> 5#include <asm/io.h>
6 6
7#define VGA_MAP_MEM(x) (PCIMEM_BASE + (x)) 7#define VGA_MAP_MEM(x,s) (PCIMEM_BASE + (x))
8 8
9#define vga_readb(x) (*((volatile unsigned char *)x)) 9#define vga_readb(x) (*((volatile unsigned char *)x))
10#define vga_writeb(x,y) (*((volatile unsigned char *)y) = (x)) 10#define vga_writeb(x,y) (*((volatile unsigned char *)y) = (x))
diff --git a/include/asm-i386/msi.h b/include/asm-i386/msi.h
index f041d4495faf..b11c4b7dfaef 100644
--- a/include/asm-i386/msi.h
+++ b/include/asm-i386/msi.h
@@ -9,7 +9,15 @@
9#include <asm/desc.h> 9#include <asm/desc.h>
10#include <mach_apic.h> 10#include <mach_apic.h>
11 11
12#define LAST_DEVICE_VECTOR 232 12#define LAST_DEVICE_VECTOR (FIRST_SYSTEM_VECTOR - 1)
13#define MSI_TARGET_CPU_SHIFT 12 13#define MSI_TARGET_CPU_SHIFT 12
14 14
15extern struct msi_ops msi_apic_ops;
16
17static inline int msi_arch_init(void)
18{
19 msi_register(&msi_apic_ops);
20 return 0;
21}
22
15#endif /* ASM_MSI_H */ 23#endif /* ASM_MSI_H */
diff --git a/include/asm-i386/vga.h b/include/asm-i386/vga.h
index ef0c0e50cc95..0ecf68ac03aa 100644
--- a/include/asm-i386/vga.h
+++ b/include/asm-i386/vga.h
@@ -12,7 +12,7 @@
12 * access the videoram directly without any black magic. 12 * access the videoram directly without any black magic.
13 */ 13 */
14 14
15#define VGA_MAP_MEM(x) (unsigned long)phys_to_virt(x) 15#define VGA_MAP_MEM(x,s) (unsigned long)phys_to_virt(x)
16 16
17#define vga_readb(x) (*(x)) 17#define vga_readb(x) (*(x))
18#define vga_writeb(x,y) (*(y) = (x)) 18#define vga_writeb(x,y) (*(y) = (x))
diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h
index 0cf119b42f7d..ea8b8c407ab4 100644
--- a/include/asm-ia64/hw_irq.h
+++ b/include/asm-ia64/hw_irq.h
@@ -47,9 +47,19 @@ typedef u8 ia64_vector;
47#define IA64_CMC_VECTOR 0x1f /* corrected machine-check interrupt vector */ 47#define IA64_CMC_VECTOR 0x1f /* corrected machine-check interrupt vector */
48/* 48/*
49 * Vectors 0x20-0x2f are reserved for legacy ISA IRQs. 49 * Vectors 0x20-0x2f are reserved for legacy ISA IRQs.
50 * Use vectors 0x30-0xe7 as the default device vector range for ia64.
51 * Platforms may choose to reduce this range in platform_irq_setup, but the
52 * platform range must fall within
53 * [IA64_DEF_FIRST_DEVICE_VECTOR..IA64_DEF_LAST_DEVICE_VECTOR]
50 */ 54 */
51#define IA64_FIRST_DEVICE_VECTOR 0x30 55extern int ia64_first_device_vector;
52#define IA64_LAST_DEVICE_VECTOR 0xe7 56extern int ia64_last_device_vector;
57
58#define IA64_DEF_FIRST_DEVICE_VECTOR 0x30
59#define IA64_DEF_LAST_DEVICE_VECTOR 0xe7
60#define IA64_FIRST_DEVICE_VECTOR ia64_first_device_vector
61#define IA64_LAST_DEVICE_VECTOR ia64_last_device_vector
62#define IA64_MAX_DEVICE_VECTORS (IA64_DEF_LAST_DEVICE_VECTOR - IA64_DEF_FIRST_DEVICE_VECTOR + 1)
53#define IA64_NUM_DEVICE_VECTORS (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1) 63#define IA64_NUM_DEVICE_VECTORS (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1)
54 64
55#define IA64_MCA_RENDEZ_VECTOR 0xe8 /* MCA rendez interrupt */ 65#define IA64_MCA_RENDEZ_VECTOR 0xe8 /* MCA rendez interrupt */
@@ -83,6 +93,7 @@ extern struct hw_interrupt_type irq_type_ia64_lsapic; /* CPU-internal interrupt
83 93
84extern int assign_irq_vector (int irq); /* allocate a free vector */ 94extern int assign_irq_vector (int irq); /* allocate a free vector */
85extern void free_irq_vector (int vector); 95extern void free_irq_vector (int vector);
96extern int reserve_irq_vector (int vector);
86extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); 97extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
87extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); 98extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
88 99
diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h
index 0df72a134c8b..15b545a897a4 100644
--- a/include/asm-ia64/machvec.h
+++ b/include/asm-ia64/machvec.h
@@ -75,6 +75,7 @@ typedef unsigned char ia64_mv_readb_relaxed_t (const volatile void __iomem *);
75typedef unsigned short ia64_mv_readw_relaxed_t (const volatile void __iomem *); 75typedef unsigned short ia64_mv_readw_relaxed_t (const volatile void __iomem *);
76typedef unsigned int ia64_mv_readl_relaxed_t (const volatile void __iomem *); 76typedef unsigned int ia64_mv_readl_relaxed_t (const volatile void __iomem *);
77typedef unsigned long ia64_mv_readq_relaxed_t (const volatile void __iomem *); 77typedef unsigned long ia64_mv_readq_relaxed_t (const volatile void __iomem *);
78typedef int ia64_mv_msi_init_t (void);
78 79
79static inline void 80static inline void
80machvec_noop (void) 81machvec_noop (void)
@@ -153,6 +154,7 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *);
153# define platform_readl_relaxed ia64_mv.readl_relaxed 154# define platform_readl_relaxed ia64_mv.readl_relaxed
154# define platform_readq_relaxed ia64_mv.readq_relaxed 155# define platform_readq_relaxed ia64_mv.readq_relaxed
155# define platform_migrate ia64_mv.migrate 156# define platform_migrate ia64_mv.migrate
157# define platform_msi_init ia64_mv.msi_init
156# endif 158# endif
157 159
158/* __attribute__((__aligned__(16))) is required to make size of the 160/* __attribute__((__aligned__(16))) is required to make size of the
@@ -202,6 +204,7 @@ struct ia64_machine_vector {
202 ia64_mv_readl_relaxed_t *readl_relaxed; 204 ia64_mv_readl_relaxed_t *readl_relaxed;
203 ia64_mv_readq_relaxed_t *readq_relaxed; 205 ia64_mv_readq_relaxed_t *readq_relaxed;
204 ia64_mv_migrate_t *migrate; 206 ia64_mv_migrate_t *migrate;
207 ia64_mv_msi_init_t *msi_init;
205} __attribute__((__aligned__(16))); /* align attrib? see above comment */ 208} __attribute__((__aligned__(16))); /* align attrib? see above comment */
206 209
207#define MACHVEC_INIT(name) \ 210#define MACHVEC_INIT(name) \
@@ -247,6 +250,7 @@ struct ia64_machine_vector {
247 platform_readl_relaxed, \ 250 platform_readl_relaxed, \
248 platform_readq_relaxed, \ 251 platform_readq_relaxed, \
249 platform_migrate, \ 252 platform_migrate, \
253 platform_msi_init, \
250} 254}
251 255
252extern struct ia64_machine_vector ia64_mv; 256extern struct ia64_machine_vector ia64_mv;
@@ -400,5 +404,8 @@ extern int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size
400#ifndef platform_migrate 404#ifndef platform_migrate
401# define platform_migrate machvec_noop_task 405# define platform_migrate machvec_noop_task
402#endif 406#endif
407#ifndef platform_msi_init
408# define platform_msi_init ((ia64_mv_msi_init_t*)NULL)
409#endif
403 410
404#endif /* _ASM_IA64_MACHVEC_H */ 411#endif /* _ASM_IA64_MACHVEC_H */
diff --git a/include/asm-ia64/machvec_sn2.h b/include/asm-ia64/machvec_sn2.h
index da1d43755afe..cf724dc79d8c 100644
--- a/include/asm-ia64/machvec_sn2.h
+++ b/include/asm-ia64/machvec_sn2.h
@@ -67,6 +67,8 @@ extern ia64_mv_dma_sync_sg_for_device sn_dma_sync_sg_for_device;
67extern ia64_mv_dma_mapping_error sn_dma_mapping_error; 67extern ia64_mv_dma_mapping_error sn_dma_mapping_error;
68extern ia64_mv_dma_supported sn_dma_supported; 68extern ia64_mv_dma_supported sn_dma_supported;
69extern ia64_mv_migrate_t sn_migrate; 69extern ia64_mv_migrate_t sn_migrate;
70extern ia64_mv_msi_init_t sn_msi_init;
71
70 72
71/* 73/*
72 * This stuff has dual use! 74 * This stuff has dual use!
@@ -117,6 +119,11 @@ extern ia64_mv_migrate_t sn_migrate;
117#define platform_dma_mapping_error sn_dma_mapping_error 119#define platform_dma_mapping_error sn_dma_mapping_error
118#define platform_dma_supported sn_dma_supported 120#define platform_dma_supported sn_dma_supported
119#define platform_migrate sn_migrate 121#define platform_migrate sn_migrate
122#ifdef CONFIG_PCI_MSI
123#define platform_msi_init sn_msi_init
124#else
125#define platform_msi_init ((ia64_mv_msi_init_t*)NULL)
126#endif
120 127
121#include <asm/sn/io.h> 128#include <asm/sn/io.h>
122 129
diff --git a/include/asm-ia64/msi.h b/include/asm-ia64/msi.h
index 97890f7762b3..bb92b0dbde2f 100644
--- a/include/asm-ia64/msi.h
+++ b/include/asm-ia64/msi.h
@@ -14,4 +14,16 @@ static inline void set_intr_gate (int nr, void *func) {}
14#define ack_APIC_irq ia64_eoi 14#define ack_APIC_irq ia64_eoi
15#define MSI_TARGET_CPU_SHIFT 4 15#define MSI_TARGET_CPU_SHIFT 4
16 16
17extern struct msi_ops msi_apic_ops;
18
19static inline int msi_arch_init(void)
20{
21 if (platform_msi_init)
22 return platform_msi_init();
23
24 /* default ops for most ia64 platforms */
25 msi_register(&msi_apic_ops);
26 return 0;
27}
28
17#endif /* ASM_MSI_H */ 29#endif /* ASM_MSI_H */
diff --git a/include/asm-ia64/sn/intr.h b/include/asm-ia64/sn/intr.h
index 60a51a406eec..12b54ddb06be 100644
--- a/include/asm-ia64/sn/intr.h
+++ b/include/asm-ia64/sn/intr.h
@@ -10,6 +10,7 @@
10#define _ASM_IA64_SN_INTR_H 10#define _ASM_IA64_SN_INTR_H
11 11
12#include <linux/rcupdate.h> 12#include <linux/rcupdate.h>
13#include <asm/sn/types.h>
13 14
14#define SGI_UART_VECTOR 0xe9 15#define SGI_UART_VECTOR 0xe9
15 16
@@ -40,6 +41,7 @@ struct sn_irq_info {
40 int irq_cpuid; /* kernel logical cpuid */ 41 int irq_cpuid; /* kernel logical cpuid */
41 int irq_irq; /* the IRQ number */ 42 int irq_irq; /* the IRQ number */
42 int irq_int_bit; /* Bridge interrupt pin */ 43 int irq_int_bit; /* Bridge interrupt pin */
44 /* <0 means MSI */
43 u64 irq_xtalkaddr; /* xtalkaddr IRQ is sent to */ 45 u64 irq_xtalkaddr; /* xtalkaddr IRQ is sent to */
44 int irq_bridge_type;/* pciio asic type (pciio.h) */ 46 int irq_bridge_type;/* pciio asic type (pciio.h) */
45 void *irq_bridge; /* bridge generating irq */ 47 void *irq_bridge; /* bridge generating irq */
@@ -53,6 +55,12 @@ struct sn_irq_info {
53}; 55};
54 56
55extern void sn_send_IPI_phys(int, long, int, int); 57extern void sn_send_IPI_phys(int, long, int, int);
58extern u64 sn_intr_alloc(nasid_t, int,
59 struct sn_irq_info *,
60 int, nasid_t, int);
61extern void sn_intr_free(nasid_t, int, struct sn_irq_info *);
62extern struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *, nasid_t, int);
63extern struct list_head **sn_irq_lh;
56 64
57#define CPU_VECTOR_TO_IRQ(cpuid,vector) (vector) 65#define CPU_VECTOR_TO_IRQ(cpuid,vector) (vector)
58 66
diff --git a/include/asm-ia64/sn/pcibr_provider.h b/include/asm-ia64/sn/pcibr_provider.h
index 51260ab70d91..e3b0c3fe5eed 100644
--- a/include/asm-ia64/sn/pcibr_provider.h
+++ b/include/asm-ia64/sn/pcibr_provider.h
@@ -55,6 +55,7 @@
55#define PCI32_ATE_V (0x1 << 0) 55#define PCI32_ATE_V (0x1 << 0)
56#define PCI32_ATE_CO (0x1 << 1) 56#define PCI32_ATE_CO (0x1 << 1)
57#define PCI32_ATE_PREC (0x1 << 2) 57#define PCI32_ATE_PREC (0x1 << 2)
58#define PCI32_ATE_MSI (0x1 << 2)
58#define PCI32_ATE_PREF (0x1 << 3) 59#define PCI32_ATE_PREF (0x1 << 3)
59#define PCI32_ATE_BAR (0x1 << 4) 60#define PCI32_ATE_BAR (0x1 << 4)
60#define PCI32_ATE_ADDR_SHFT 12 61#define PCI32_ATE_ADDR_SHFT 12
@@ -117,8 +118,8 @@ struct pcibus_info {
117 118
118extern int pcibr_init_provider(void); 119extern int pcibr_init_provider(void);
119extern void *pcibr_bus_fixup(struct pcibus_bussoft *, struct pci_controller *); 120extern void *pcibr_bus_fixup(struct pcibus_bussoft *, struct pci_controller *);
120extern dma_addr_t pcibr_dma_map(struct pci_dev *, unsigned long, size_t); 121extern dma_addr_t pcibr_dma_map(struct pci_dev *, unsigned long, size_t, int type);
121extern dma_addr_t pcibr_dma_map_consistent(struct pci_dev *, unsigned long, size_t); 122extern dma_addr_t pcibr_dma_map_consistent(struct pci_dev *, unsigned long, size_t, int type);
122extern void pcibr_dma_unmap(struct pci_dev *, dma_addr_t, int); 123extern void pcibr_dma_unmap(struct pci_dev *, dma_addr_t, int);
123 124
124/* 125/*
diff --git a/include/asm-ia64/sn/pcibus_provider_defs.h b/include/asm-ia64/sn/pcibus_provider_defs.h
index ce3f6c328241..8f7c83d0f6d3 100644
--- a/include/asm-ia64/sn/pcibus_provider_defs.h
+++ b/include/asm-ia64/sn/pcibus_provider_defs.h
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 1992 - 1997, 2000-2004 Silicon Graphics, Inc. All rights reserved. 6 * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved.
7 */ 7 */
8#ifndef _ASM_IA64_SN_PCI_PCIBUS_PROVIDER_H 8#ifndef _ASM_IA64_SN_PCI_PCIBUS_PROVIDER_H
9#define _ASM_IA64_SN_PCI_PCIBUS_PROVIDER_H 9#define _ASM_IA64_SN_PCI_PCIBUS_PROVIDER_H
@@ -45,13 +45,24 @@ struct pci_controller;
45 */ 45 */
46 46
47struct sn_pcibus_provider { 47struct sn_pcibus_provider {
48 dma_addr_t (*dma_map)(struct pci_dev *, unsigned long, size_t); 48 dma_addr_t (*dma_map)(struct pci_dev *, unsigned long, size_t, int flags);
49 dma_addr_t (*dma_map_consistent)(struct pci_dev *, unsigned long, size_t); 49 dma_addr_t (*dma_map_consistent)(struct pci_dev *, unsigned long, size_t, int flags);
50 void (*dma_unmap)(struct pci_dev *, dma_addr_t, int); 50 void (*dma_unmap)(struct pci_dev *, dma_addr_t, int);
51 void * (*bus_fixup)(struct pcibus_bussoft *, struct pci_controller *); 51 void * (*bus_fixup)(struct pcibus_bussoft *, struct pci_controller *);
52 void (*force_interrupt)(struct sn_irq_info *); 52 void (*force_interrupt)(struct sn_irq_info *);
53 void (*target_interrupt)(struct sn_irq_info *); 53 void (*target_interrupt)(struct sn_irq_info *);
54}; 54};
55 55
56/*
57 * Flags used by the map interfaces
58 * bits 3:0 specifies format of passed in address
59 * bit 4 specifies that address is to be used for MSI
60 */
61
62#define SN_DMA_ADDRTYPE(x) ((x) & 0xf)
63#define SN_DMA_ADDR_PHYS 1 /* address is an xio address. */
64#define SN_DMA_ADDR_XIO 2 /* address is phys memory */
65#define SN_DMA_MSI 0x10 /* Bus address is to be used for MSI */
66
56extern struct sn_pcibus_provider *sn_pci_provider[]; 67extern struct sn_pcibus_provider *sn_pci_provider[];
57#endif /* _ASM_IA64_SN_PCI_PCIBUS_PROVIDER_H */ 68#endif /* _ASM_IA64_SN_PCI_PCIBUS_PROVIDER_H */
diff --git a/include/asm-ia64/sn/tiocp.h b/include/asm-ia64/sn/tiocp.h
index f47c08ab483c..e8ad0bb5b6c5 100644
--- a/include/asm-ia64/sn/tiocp.h
+++ b/include/asm-ia64/sn/tiocp.h
@@ -3,13 +3,14 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2003-2004 Silicon Graphics, Inc. All rights reserved. 6 * Copyright (C) 2003-2005 Silicon Graphics, Inc. All rights reserved.
7 */ 7 */
8#ifndef _ASM_IA64_SN_PCI_TIOCP_H 8#ifndef _ASM_IA64_SN_PCI_TIOCP_H
9#define _ASM_IA64_SN_PCI_TIOCP_H 9#define _ASM_IA64_SN_PCI_TIOCP_H
10 10
11#define TIOCP_HOST_INTR_ADDR 0x003FFFFFFFFFFFFFUL 11#define TIOCP_HOST_INTR_ADDR 0x003FFFFFFFFFFFFFUL
12#define TIOCP_PCI64_CMDTYPE_MEM (0x1ull << 60) 12#define TIOCP_PCI64_CMDTYPE_MEM (0x1ull << 60)
13#define TIOCP_PCI64_CMDTYPE_MSI (0x3ull << 60)
13 14
14 15
15/***************************************************************************** 16/*****************************************************************************
diff --git a/include/asm-ia64/vga.h b/include/asm-ia64/vga.h
index 091177cda223..02184ecd8208 100644
--- a/include/asm-ia64/vga.h
+++ b/include/asm-ia64/vga.h
@@ -17,7 +17,7 @@
17extern unsigned long vga_console_iobase; 17extern unsigned long vga_console_iobase;
18extern unsigned long vga_console_membase; 18extern unsigned long vga_console_membase;
19 19
20#define VGA_MAP_MEM(x) ((unsigned long) ioremap_nocache(vga_console_membase + (x), 0)) 20#define VGA_MAP_MEM(x,s) ((unsigned long) ioremap_nocache(vga_console_membase + (x), s))
21 21
22#define vga_readb(x) (*(x)) 22#define vga_readb(x) (*(x))
23#define vga_writeb(x,y) (*(y) = (x)) 23#define vga_writeb(x,y) (*(y) = (x))
diff --git a/include/asm-m32r/vga.h b/include/asm-m32r/vga.h
index d0f4b6eed7a3..533163447cc9 100644
--- a/include/asm-m32r/vga.h
+++ b/include/asm-m32r/vga.h
@@ -14,7 +14,7 @@
14 * access the videoram directly without any black magic. 14 * access the videoram directly without any black magic.
15 */ 15 */
16 16
17#define VGA_MAP_MEM(x) (unsigned long)phys_to_virt(x) 17#define VGA_MAP_MEM(x,s) (unsigned long)phys_to_virt(x)
18 18
19#define vga_readb(x) (*(x)) 19#define vga_readb(x) (*(x))
20#define vga_writeb(x,y) (*(y) = (x)) 20#define vga_writeb(x,y) (*(y) = (x))
diff --git a/include/asm-mips/vga.h b/include/asm-mips/vga.h
index 34755c0a6398..c1dd0b10bc27 100644
--- a/include/asm-mips/vga.h
+++ b/include/asm-mips/vga.h
@@ -13,7 +13,7 @@
13 * access the videoram directly without any black magic. 13 * access the videoram directly without any black magic.
14 */ 14 */
15 15
16#define VGA_MAP_MEM(x) (0xb0000000L + (unsigned long)(x)) 16#define VGA_MAP_MEM(x,s) (0xb0000000L + (unsigned long)(x))
17 17
18#define vga_readb(x) (*(x)) 18#define vga_readb(x) (*(x))
19#define vga_writeb(x,y) (*(y) = (x)) 19#define vga_writeb(x,y) (*(y) = (x))
diff --git a/include/asm-powerpc/vga.h b/include/asm-powerpc/vga.h
index eadaf2f3d032..a2eac409c1ec 100644
--- a/include/asm-powerpc/vga.h
+++ b/include/asm-powerpc/vga.h
@@ -41,9 +41,9 @@ static inline u16 scr_readw(volatile const u16 *addr)
41extern unsigned long vgacon_remap_base; 41extern unsigned long vgacon_remap_base;
42 42
43#ifdef __powerpc64__ 43#ifdef __powerpc64__
44#define VGA_MAP_MEM(x) ((unsigned long) ioremap((x), 0)) 44#define VGA_MAP_MEM(x,s) ((unsigned long) ioremap((x), s))
45#else 45#else
46#define VGA_MAP_MEM(x) (x + vgacon_remap_base) 46#define VGA_MAP_MEM(x,s) (x + vgacon_remap_base)
47#endif 47#endif
48 48
49#define vga_readb(x) (*(x)) 49#define vga_readb(x) (*(x))
diff --git a/include/asm-sparc64/vga.h b/include/asm-sparc64/vga.h
index 9c57eb363b40..c69d5b2ba19a 100644
--- a/include/asm-sparc64/vga.h
+++ b/include/asm-sparc64/vga.h
@@ -28,6 +28,6 @@ static inline u16 scr_readw(const u16 *addr)
28 return *addr; 28 return *addr;
29} 29}
30 30
31#define VGA_MAP_MEM(x) (x) 31#define VGA_MAP_MEM(x,s) (x)
32 32
33#endif 33#endif
diff --git a/include/asm-x86_64/msi.h b/include/asm-x86_64/msi.h
index 356e0e82f50b..3ad2346624b2 100644
--- a/include/asm-x86_64/msi.h
+++ b/include/asm-x86_64/msi.h
@@ -10,7 +10,15 @@
10#include <asm/mach_apic.h> 10#include <asm/mach_apic.h>
11#include <asm/smp.h> 11#include <asm/smp.h>
12 12
13#define LAST_DEVICE_VECTOR 232 13#define LAST_DEVICE_VECTOR (FIRST_SYSTEM_VECTOR - 1)
14#define MSI_TARGET_CPU_SHIFT 12 14#define MSI_TARGET_CPU_SHIFT 12
15 15
16extern struct msi_ops msi_apic_ops;
17
18static inline int msi_arch_init(void)
19{
20 msi_register(&msi_apic_ops);
21 return 0;
22}
23
16#endif /* ASM_MSI_H */ 24#endif /* ASM_MSI_H */
diff --git a/include/asm-x86_64/vga.h b/include/asm-x86_64/vga.h
index ef0c0e50cc95..0ecf68ac03aa 100644
--- a/include/asm-x86_64/vga.h
+++ b/include/asm-x86_64/vga.h
@@ -12,7 +12,7 @@
12 * access the videoram directly without any black magic. 12 * access the videoram directly without any black magic.
13 */ 13 */
14 14
15#define VGA_MAP_MEM(x) (unsigned long)phys_to_virt(x) 15#define VGA_MAP_MEM(x,s) (unsigned long)phys_to_virt(x)
16 16
17#define vga_readb(x) (*(x)) 17#define vga_readb(x) (*(x))
18#define vga_writeb(x,y) (*(y) = (x)) 18#define vga_writeb(x,y) (*(y) = (x))
diff --git a/include/asm-xtensa/vga.h b/include/asm-xtensa/vga.h
index 23d82f6acb57..1fd8cab3a297 100644
--- a/include/asm-xtensa/vga.h
+++ b/include/asm-xtensa/vga.h
@@ -11,7 +11,7 @@
11#ifndef _XTENSA_VGA_H 11#ifndef _XTENSA_VGA_H
12#define _XTENSA_VGA_H 12#define _XTENSA_VGA_H
13 13
14#define VGA_MAP_MEM(x) (unsigned long)phys_to_virt(x) 14#define VGA_MAP_MEM(x,s) (unsigned long)phys_to_virt(x)
15 15
16#define vga_readb(x) (*(x)) 16#define vga_readb(x) (*(x))
17#define vga_writeb(x,y) (*(y) = (x)) 17#define vga_writeb(x,y) (*(y) = (x))
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 836325ee0931..46d0e079735d 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -217,7 +217,7 @@ extern struct dentry * d_alloc_anon(struct inode *);
217extern struct dentry * d_splice_alias(struct inode *, struct dentry *); 217extern struct dentry * d_splice_alias(struct inode *, struct dentry *);
218extern void shrink_dcache_sb(struct super_block *); 218extern void shrink_dcache_sb(struct super_block *);
219extern void shrink_dcache_parent(struct dentry *); 219extern void shrink_dcache_parent(struct dentry *);
220extern void shrink_dcache_anon(struct hlist_head *); 220extern void shrink_dcache_anon(struct super_block *);
221extern int d_invalidate(struct dentry *); 221extern int d_invalidate(struct dentry *);
222 222
223/* only used at mount-time */ 223/* only used at mount-time */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index ecc8c2c3d8ca..73c7d6f04b31 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -782,7 +782,6 @@ extern int setlease(struct file *, long, struct file_lock **);
782extern int lease_modify(struct file_lock **, int); 782extern int lease_modify(struct file_lock **, int);
783extern int lock_may_read(struct inode *, loff_t start, unsigned long count); 783extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
784extern int lock_may_write(struct inode *, loff_t start, unsigned long count); 784extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
785extern void steal_locks(fl_owner_t from);
786 785
787struct fasync_struct { 786struct fasync_struct {
788 int magic; 787 int magic;
diff --git a/include/linux/key.h b/include/linux/key.h
index cbf464ad9589..e81ebf910d0b 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -205,6 +205,11 @@ struct key_type {
205 /* match a key against a description */ 205 /* match a key against a description */
206 int (*match)(const struct key *key, const void *desc); 206 int (*match)(const struct key *key, const void *desc);
207 207
208 /* clear some of the data from a key on revokation (optional)
209 * - the key's semaphore will be write-locked by the caller
210 */
211 void (*revoke)(struct key *key);
212
208 /* clear the data from a key (optional) */ 213 /* clear the data from a key (optional) */
209 void (*destroy)(struct key *key); 214 void (*destroy)(struct key *key);
210 215
@@ -241,8 +246,9 @@ extern void unregister_key_type(struct key_type *ktype);
241 246
242extern struct key *key_alloc(struct key_type *type, 247extern struct key *key_alloc(struct key_type *type,
243 const char *desc, 248 const char *desc,
244 uid_t uid, gid_t gid, key_perm_t perm, 249 uid_t uid, gid_t gid,
245 int not_in_quota); 250 struct task_struct *ctx,
251 key_perm_t perm, int not_in_quota);
246extern int key_payload_reserve(struct key *key, size_t datalen); 252extern int key_payload_reserve(struct key *key, size_t datalen);
247extern int key_instantiate_and_link(struct key *key, 253extern int key_instantiate_and_link(struct key *key,
248 const void *data, 254 const void *data,
@@ -292,7 +298,9 @@ extern int key_unlink(struct key *keyring,
292 struct key *key); 298 struct key *key);
293 299
294extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 300extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
295 int not_in_quota, struct key *dest); 301 struct task_struct *ctx,
302 int not_in_quota,
303 struct key *dest);
296 304
297extern int keyring_clear(struct key *keyring); 305extern int keyring_clear(struct key *keyring);
298 306
@@ -313,7 +321,8 @@ extern void keyring_replace_payload(struct key *key, void *replacement);
313 * the userspace interface 321 * the userspace interface
314 */ 322 */
315extern struct key root_user_keyring, root_session_keyring; 323extern struct key root_user_keyring, root_session_keyring;
316extern int alloc_uid_keyring(struct user_struct *user); 324extern int alloc_uid_keyring(struct user_struct *user,
325 struct task_struct *ctx);
317extern void switch_uid_keyring(struct user_struct *new_user); 326extern void switch_uid_keyring(struct user_struct *new_user);
318extern int copy_keys(unsigned long clone_flags, struct task_struct *tsk); 327extern int copy_keys(unsigned long clone_flags, struct task_struct *tsk);
319extern int copy_thread_group_keys(struct task_struct *tsk); 328extern int copy_thread_group_keys(struct task_struct *tsk);
@@ -342,7 +351,7 @@ extern void key_init(void);
342#define make_key_ref(k) ({ NULL; }) 351#define make_key_ref(k) ({ NULL; })
343#define key_ref_to_ptr(k) ({ NULL; }) 352#define key_ref_to_ptr(k) ({ NULL; })
344#define is_key_possessed(k) 0 353#define is_key_possessed(k) 0
345#define alloc_uid_keyring(u) 0 354#define alloc_uid_keyring(u,c) 0
346#define switch_uid_keyring(u) do { } while(0) 355#define switch_uid_keyring(u) do { } while(0)
347#define __install_session_keyring(t, k) ({ NULL; }) 356#define __install_session_keyring(t, k) ({ NULL; })
348#define copy_keys(f,t) 0 357#define copy_keys(f,t) 0
@@ -355,6 +364,10 @@ extern void key_init(void);
355#define key_fsgid_changed(t) do { } while(0) 364#define key_fsgid_changed(t) do { } while(0)
356#define key_init() do { } while(0) 365#define key_init() do { } while(0)
357 366
367/* Initial keyrings */
368extern struct key root_user_keyring;
369extern struct key root_session_keyring;
370
358#endif /* CONFIG_KEYS */ 371#endif /* CONFIG_KEYS */
359#endif /* __KERNEL__ */ 372#endif /* __KERNEL__ */
360#endif /* _LINUX_KEY_H */ 373#endif /* _LINUX_KEY_H */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6c4bc773f7b7..62a8c22f5f60 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -162,6 +162,9 @@ struct pci_dev {
162 unsigned int is_busmaster:1; /* device is busmaster */ 162 unsigned int is_busmaster:1; /* device is busmaster */
163 unsigned int no_msi:1; /* device may not use msi */ 163 unsigned int no_msi:1; /* device may not use msi */
164 unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ 164 unsigned int block_ucfg_access:1; /* userspace config space access is blocked */
165 unsigned int broken_parity_status:1; /* Device generates false positive parity */
166 unsigned int msi_enabled:1;
167 unsigned int msix_enabled:1;
165 168
166 u32 saved_config_space[16]; /* config space saved at suspend time */ 169 u32 saved_config_space[16]; /* config space saved at suspend time */
167 struct hlist_head saved_cap_space; 170 struct hlist_head saved_cap_space;
@@ -496,6 +499,7 @@ int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
496int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); 499int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
497void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); 500void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
498int pci_assign_resource(struct pci_dev *dev, int i); 501int pci_assign_resource(struct pci_dev *dev, int i);
502int pci_assign_resource_fixed(struct pci_dev *dev, int i);
499void pci_restore_bars(struct pci_dev *dev); 503void pci_restore_bars(struct pci_dev *dev);
500 504
501/* ROM control related routines */ 505/* ROM control related routines */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index bcfe9d4f56ae..fd54a9d4c3d4 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -848,7 +848,12 @@
848 848
849 849
850#define PCI_VENDOR_ID_QLOGIC 0x1077 850#define PCI_VENDOR_ID_QLOGIC 0x1077
851#define PCI_DEVICE_ID_QLOGIC_ISP10160 0x1016
851#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020 852#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020
853#define PCI_DEVICE_ID_QLOGIC_ISP1080 0x1080
854#define PCI_DEVICE_ID_QLOGIC_ISP12160 0x1216
855#define PCI_DEVICE_ID_QLOGIC_ISP1240 0x1240
856#define PCI_DEVICE_ID_QLOGIC_ISP1280 0x1280
852#define PCI_DEVICE_ID_QLOGIC_ISP2100 0x2100 857#define PCI_DEVICE_ID_QLOGIC_ISP2100 0x2100
853#define PCI_DEVICE_ID_QLOGIC_ISP2200 0x2200 858#define PCI_DEVICE_ID_QLOGIC_ISP2200 0x2200
854#define PCI_DEVICE_ID_QLOGIC_ISP2300 0x2300 859#define PCI_DEVICE_ID_QLOGIC_ISP2300 0x2300
@@ -1018,6 +1023,7 @@
1018#define PCI_DEVICE_ID_NVIDIA_NVENET_8 0x0056 1023#define PCI_DEVICE_ID_NVIDIA_NVENET_8 0x0056
1019#define PCI_DEVICE_ID_NVIDIA_NVENET_9 0x0057 1024#define PCI_DEVICE_ID_NVIDIA_NVENET_9 0x0057
1020#define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059 1025#define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059
1026#define PCI_DEVICE_ID_NVIDIA_CK804_PCIE 0x005d
1021#define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS 0x0064 1027#define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS 0x0064
1022#define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE 0x0065 1028#define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE 0x0065
1023#define PCI_DEVICE_ID_NVIDIA_NVENET_2 0x0066 1029#define PCI_DEVICE_ID_NVIDIA_NVENET_2 0x0066
@@ -1946,6 +1952,7 @@
1946 1952
1947#define PCI_VENDOR_ID_MELLANOX 0x15b3 1953#define PCI_VENDOR_ID_MELLANOX 0x15b3
1948#define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44 1954#define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44
1955#define PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE 0x5a46
1949#define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278 1956#define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278
1950#define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282 1957#define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282
1951#define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c 1958#define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c
@@ -1969,6 +1976,9 @@
1969#define PCI_VENDOR_ID_NETCELL 0x169c 1976#define PCI_VENDOR_ID_NETCELL 0x169c
1970#define PCI_DEVICE_ID_REVOLUTION 0x0044 1977#define PCI_DEVICE_ID_REVOLUTION 0x0044
1971 1978
1979#define PCI_VENDOR_ID_VITESSE 0x1725
1980#define PCI_DEVICE_ID_VITESSE_VSC7174 0x7174
1981
1972#define PCI_VENDOR_ID_LINKSYS 0x1737 1982#define PCI_VENDOR_ID_LINKSYS 0x1737
1973#define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064 1983#define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064
1974 1984
@@ -2148,6 +2158,7 @@
2148#define PCI_DEVICE_ID_INTEL_ICH8_4 0x2815 2158#define PCI_DEVICE_ID_INTEL_ICH8_4 0x2815
2149#define PCI_DEVICE_ID_INTEL_ICH8_5 0x283e 2159#define PCI_DEVICE_ID_INTEL_ICH8_5 0x283e
2150#define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850 2160#define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850
2161#define PCI_DEVICE_ID_INTEL_GD31244 0x3200
2151#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 2162#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
2152#define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 2163#define PCI_DEVICE_ID_INTEL_82830_HB 0x3575
2153#define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 2164#define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index d27a78b71297..6bce4a240364 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -197,6 +197,7 @@
197#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */ 197#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
198#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */ 198#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */
199#define PCI_CAP_ID_HT_IRQCONF 0x08 /* HyperTransport IRQ Configuration */ 199#define PCI_CAP_ID_HT_IRQCONF 0x08 /* HyperTransport IRQ Configuration */
200#define PCI_CAP_ID_VNDR 0x09 /* Vendor specific capability */
200#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */ 201#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
201#define PCI_CAP_ID_EXP 0x10 /* PCI Express */ 202#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
202#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ 203#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
diff --git a/include/linux/security.h b/include/linux/security.h
index 4dfb1b84a9b3..47722d355532 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1313,7 +1313,7 @@ struct security_operations {
1313 1313
1314 /* key management security hooks */ 1314 /* key management security hooks */
1315#ifdef CONFIG_KEYS 1315#ifdef CONFIG_KEYS
1316 int (*key_alloc)(struct key *key); 1316 int (*key_alloc)(struct key *key, struct task_struct *tsk);
1317 void (*key_free)(struct key *key); 1317 void (*key_free)(struct key *key);
1318 int (*key_permission)(key_ref_t key_ref, 1318 int (*key_permission)(key_ref_t key_ref,
1319 struct task_struct *context, 1319 struct task_struct *context,
@@ -3008,9 +3008,10 @@ static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid
3008 3008
3009#ifdef CONFIG_KEYS 3009#ifdef CONFIG_KEYS
3010#ifdef CONFIG_SECURITY 3010#ifdef CONFIG_SECURITY
3011static inline int security_key_alloc(struct key *key) 3011static inline int security_key_alloc(struct key *key,
3012 struct task_struct *tsk)
3012{ 3013{
3013 return security_ops->key_alloc(key); 3014 return security_ops->key_alloc(key, tsk);
3014} 3015}
3015 3016
3016static inline void security_key_free(struct key *key) 3017static inline void security_key_free(struct key *key)
@@ -3027,7 +3028,8 @@ static inline int security_key_permission(key_ref_t key_ref,
3027 3028
3028#else 3029#else
3029 3030
3030static inline int security_key_alloc(struct key *key) 3031static inline int security_key_alloc(struct key *key,
3032 struct task_struct *tsk)
3031{ 3033{
3032 return 0; 3034 return 0;
3033} 3035}
diff --git a/include/linux/zconf.h b/include/linux/zconf.h
index f1cfd66b9554..0beb75e38caa 100644
--- a/include/linux/zconf.h
+++ b/include/linux/zconf.h
@@ -35,6 +35,18 @@
35# define MAX_WBITS 15 /* 32K LZ77 window */ 35# define MAX_WBITS 15 /* 32K LZ77 window */
36#endif 36#endif
37 37
38/* default windowBits for decompression. MAX_WBITS is for compression only */
39#ifndef DEF_WBITS
40# define DEF_WBITS MAX_WBITS
41#endif
42
43/* default memLevel */
44#if MAX_MEM_LEVEL >= 8
45# define DEF_MEM_LEVEL 8
46#else
47# define DEF_MEM_LEVEL MAX_MEM_LEVEL
48#endif
49
38 /* Type declarations */ 50 /* Type declarations */
39 51
40typedef unsigned char Byte; /* 8 bits */ 52typedef unsigned char Byte; /* 8 bits */
diff --git a/include/linux/zlib.h b/include/linux/zlib.h
index 4fa32f0d4df8..9e3192a7dc6f 100644
--- a/include/linux/zlib.h
+++ b/include/linux/zlib.h
@@ -1,7 +1,6 @@
1/* zlib.h -- interface of the 'zlib' general purpose compression library 1/* zlib.h -- interface of the 'zlib' general purpose compression library
2 version 1.1.3, July 9th, 1998
3 2
4 Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler 3 Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
5 4
6 This software is provided 'as-is', without any express or implied 5 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages 6 warranty. In no event will the authors be held liable for any damages
@@ -24,7 +23,7 @@
24 23
25 24
26 The data format used by the zlib library is described by RFCs (Request for 25 The data format used by the zlib library is described by RFCs (Request for
27 Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt 26 Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
28 (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). 27 (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
29*/ 28*/
30 29
@@ -33,7 +32,22 @@
33 32
34#include <linux/zconf.h> 33#include <linux/zconf.h>
35 34
36#define ZLIB_VERSION "1.1.3" 35/* zlib deflate based on ZLIB_VERSION "1.1.3" */
36/* zlib inflate based on ZLIB_VERSION "1.2.3" */
37
38/*
39 This is a modified version of zlib for use inside the Linux kernel.
40 The main changes are to perform all memory allocation in advance.
41
42 Inflation Changes:
43 * Z_PACKET_FLUSH is added and used by ppp_deflate. Before returning
44 this checks there is no more input data available and the next data
45 is a STORED block. It also resets the mode to be read for the next
46 data, all as per PPP requirements.
47 * Addition of zlib_inflateIncomp which copies incompressible data into
48 the history window and adjusts the accoutning without calling
49 zlib_inflate itself to inflate the data.
50*/
37 51
38/* 52/*
39 The 'zlib' compression library provides in-memory compression and 53 The 'zlib' compression library provides in-memory compression and
@@ -48,9 +62,18 @@
48 application must provide more input and/or consume the output 62 application must provide more input and/or consume the output
49 (providing more output space) before each call. 63 (providing more output space) before each call.
50 64
65 The compressed data format used by default by the in-memory functions is
66 the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
67 around a deflate stream, which is itself documented in RFC 1951.
68
51 The library also supports reading and writing files in gzip (.gz) format 69 The library also supports reading and writing files in gzip (.gz) format
52 with an interface similar to that of stdio. 70 with an interface similar to that of stdio.
53 71
72 The zlib format was designed to be compact and fast for use in memory
73 and on communications channels. The gzip format was designed for single-
74 file compression on file systems, has a larger header than zlib to maintain
75 directory information, and uses a different, slower check method than zlib.
76
54 The library does not install any signal handler. The decoder checks 77 The library does not install any signal handler. The decoder checks
55 the consistency of the compressed data, so the library should never 78 the consistency of the compressed data, so the library should never
56 crash even in case of corrupted input. 79 crash even in case of corrupted input.
@@ -119,7 +142,8 @@ typedef z_stream *z_streamp;
119#define Z_SYNC_FLUSH 3 142#define Z_SYNC_FLUSH 3
120#define Z_FULL_FLUSH 4 143#define Z_FULL_FLUSH 4
121#define Z_FINISH 5 144#define Z_FINISH 5
122/* Allowed flush values; see deflate() below for details */ 145#define Z_BLOCK 6 /* Only for inflate at present */
146/* Allowed flush values; see deflate() and inflate() below for details */
123 147
124#define Z_OK 0 148#define Z_OK 0
125#define Z_STREAM_END 1 149#define Z_STREAM_END 1
@@ -155,13 +179,6 @@ typedef z_stream *z_streamp;
155 179
156 /* basic functions */ 180 /* basic functions */
157 181
158extern const char * zlib_zlibVersion (void);
159/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
160 If the first character differs, the library code actually used is
161 not compatible with the zlib.h header file used by the application.
162 This check is automatically made by deflateInit and inflateInit.
163 */
164
165extern int zlib_deflate_workspacesize (void); 182extern int zlib_deflate_workspacesize (void);
166/* 183/*
167 Returns the number of bytes that needs to be allocated for a per- 184 Returns the number of bytes that needs to be allocated for a per-
@@ -315,9 +332,9 @@ extern int zlib_inflateInit (z_streamp strm);
315extern int zlib_inflate (z_streamp strm, int flush); 332extern int zlib_inflate (z_streamp strm, int flush);
316/* 333/*
317 inflate decompresses as much data as possible, and stops when the input 334 inflate decompresses as much data as possible, and stops when the input
318 buffer becomes empty or the output buffer becomes full. It may some 335 buffer becomes empty or the output buffer becomes full. It may introduce
319 introduce some output latency (reading input without producing any output) 336 some output latency (reading input without producing any output) except when
320 except when forced to flush. 337 forced to flush.
321 338
322 The detailed semantics are as follows. inflate performs one or both of the 339 The detailed semantics are as follows. inflate performs one or both of the
323 following actions: 340 following actions:
@@ -341,11 +358,26 @@ extern int zlib_inflate (z_streamp strm, int flush);
341 must be called again after making room in the output buffer because there 358 must be called again after making room in the output buffer because there
342 might be more output pending. 359 might be more output pending.
343 360
344 If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much 361 The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
345 output as possible to the output buffer. The flushing behavior of inflate is 362 Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
346 not specified for values of the flush parameter other than Z_SYNC_FLUSH 363 output as possible to the output buffer. Z_BLOCK requests that inflate() stop
347 and Z_FINISH, but the current implementation actually flushes as much output 364 if and when it gets to the next deflate block boundary. When decoding the
348 as possible anyway. 365 zlib or gzip format, this will cause inflate() to return immediately after
366 the header and before the first block. When doing a raw inflate, inflate()
367 will go ahead and process the first block, and will return when it gets to
368 the end of that block, or when it runs out of data.
369
370 The Z_BLOCK option assists in appending to or combining deflate streams.
371 Also to assist in this, on return inflate() will set strm->data_type to the
372 number of unused bits in the last byte taken from strm->next_in, plus 64
373 if inflate() is currently decoding the last block in the deflate stream,
374 plus 128 if inflate() returned immediately after decoding an end-of-block
375 code or decoding the complete header up to just before the first byte of the
376 deflate stream. The end-of-block will not be indicated until all of the
377 uncompressed data from that block has been written to strm->next_out. The
378 number of unused bits may in general be greater than seven, except when
379 bit 7 of data_type is set, in which case the number of unused bits will be
380 less than eight.
349 381
350 inflate() should normally be called until it returns Z_STREAM_END or an 382 inflate() should normally be called until it returns Z_STREAM_END or an
351 error. However if all decompression is to be performed in a single step 383 error. However if all decompression is to be performed in a single step
@@ -355,29 +387,44 @@ extern int zlib_inflate (z_streamp strm, int flush);
355 uncompressed data. (The size of the uncompressed data may have been saved 387 uncompressed data. (The size of the uncompressed data may have been saved
356 by the compressor for this purpose.) The next operation on this stream must 388 by the compressor for this purpose.) The next operation on this stream must
357 be inflateEnd to deallocate the decompression state. The use of Z_FINISH 389 be inflateEnd to deallocate the decompression state. The use of Z_FINISH
358 is never required, but can be used to inform inflate that a faster routine 390 is never required, but can be used to inform inflate that a faster approach
359 may be used for the single inflate() call. 391 may be used for the single inflate() call.
360 392
361 If a preset dictionary is needed at this point (see inflateSetDictionary 393 In this implementation, inflate() always flushes as much output as
362 below), inflate sets strm-adler to the adler32 checksum of the 394 possible to the output buffer, and always uses the faster approach on the
363 dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise 395 first call. So the only effect of the flush parameter in this implementation
364 it sets strm->adler to the adler32 checksum of all output produced 396 is on the return value of inflate(), as noted below, or when it returns early
365 so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or 397 because Z_BLOCK is used.
366 an error code as described below. At the end of the stream, inflate() 398
367 checks that its computed adler32 checksum is equal to that saved by the 399 If a preset dictionary is needed after this call (see inflateSetDictionary
368 compressor and returns Z_STREAM_END only if the checksum is correct. 400 below), inflate sets strm->adler to the adler32 checksum of the dictionary
401 chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
402 strm->adler to the adler32 checksum of all output produced so far (that is,
403 total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
404 below. At the end of the stream, inflate() checks that its computed adler32
405 checksum is equal to that saved by the compressor and returns Z_STREAM_END
406 only if the checksum is correct.
407
408 inflate() will decompress and check either zlib-wrapped or gzip-wrapped
409 deflate data. The header type is detected automatically. Any information
410 contained in the gzip header is not retained, so applications that need that
411 information should instead use raw inflate, see inflateInit2() below, or
412 inflateBack() and perform their own processing of the gzip header and
413 trailer.
369 414
370 inflate() returns Z_OK if some progress has been made (more input processed 415 inflate() returns Z_OK if some progress has been made (more input processed
371 or more output produced), Z_STREAM_END if the end of the compressed data has 416 or more output produced), Z_STREAM_END if the end of the compressed data has
372 been reached and all uncompressed output has been produced, Z_NEED_DICT if a 417 been reached and all uncompressed output has been produced, Z_NEED_DICT if a
373 preset dictionary is needed at this point, Z_DATA_ERROR if the input data was 418 preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
374 corrupted (input stream not conforming to the zlib format or incorrect 419 corrupted (input stream not conforming to the zlib format or incorrect check
375 adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent 420 value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
376 (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not 421 if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
377 enough memory, Z_BUF_ERROR if no progress is possible or if there was not 422 Z_BUF_ERROR if no progress is possible or if there was not enough room in the
378 enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR 423 output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
379 case, the application may then call inflateSync to look for a good 424 inflate() can be called again with more input and more output space to
380 compression block. 425 continue decompressing. If Z_DATA_ERROR is returned, the application may then
426 call inflateSync() to look for a good compression block if a partial recovery
427 of the data is desired.
381*/ 428*/
382 429
383 430
@@ -547,16 +594,36 @@ extern int inflateInit2 (z_streamp strm, int windowBits);
547 The windowBits parameter is the base two logarithm of the maximum window 594 The windowBits parameter is the base two logarithm of the maximum window
548 size (the size of the history buffer). It should be in the range 8..15 for 595 size (the size of the history buffer). It should be in the range 8..15 for
549 this version of the library. The default value is 15 if inflateInit is used 596 this version of the library. The default value is 15 if inflateInit is used
550 instead. If a compressed stream with a larger window size is given as 597 instead. windowBits must be greater than or equal to the windowBits value
551 input, inflate() will return with the error code Z_DATA_ERROR instead of 598 provided to deflateInit2() while compressing, or it must be equal to 15 if
552 trying to allocate a larger window. 599 deflateInit2() was not used. If a compressed stream with a larger window
553 600 size is given as input, inflate() will return with the error code
554 inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 601 Z_DATA_ERROR instead of trying to allocate a larger window.
555 memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative 602
556 memLevel). msg is set to null if there is no error message. inflateInit2 603 windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
557 does not perform any decompression apart from reading the zlib header if 604 determines the window size. inflate() will then process raw deflate data,
558 present: this will be done by inflate(). (So next_in and avail_in may be 605 not looking for a zlib or gzip header, not generating a check value, and not
559 modified, but next_out and avail_out are unchanged.) 606 looking for any check values for comparison at the end of the stream. This
607 is for use with other formats that use the deflate compressed data format
608 such as zip. Those formats provide their own check values. If a custom
609 format is developed using the raw deflate format for compressed data, it is
610 recommended that a check value such as an adler32 or a crc32 be applied to
611 the uncompressed data as is done in the zlib, gzip, and zip formats. For
612 most applications, the zlib format should be used as is. Note that comments
613 above on the use in deflateInit2() applies to the magnitude of windowBits.
614
615 windowBits can also be greater than 15 for optional gzip decoding. Add
616 32 to windowBits to enable zlib and gzip decoding with automatic header
617 detection, or add 16 to decode only the gzip format (the zlib format will
618 return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
619 a crc32 instead of an adler32.
620
621 inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
622 memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
623 is set to null if there is no error message. inflateInit2 does not perform
624 any decompression apart from reading the zlib header if present: this will
625 be done by inflate(). (So next_in and avail_in may be modified, but next_out
626 and avail_out are unchanged.)
560*/ 627*/
561 628
562extern int zlib_inflateSetDictionary (z_streamp strm, 629extern int zlib_inflateSetDictionary (z_streamp strm,
@@ -564,16 +631,19 @@ extern int zlib_inflateSetDictionary (z_streamp strm,
564 uInt dictLength); 631 uInt dictLength);
565/* 632/*
566 Initializes the decompression dictionary from the given uncompressed byte 633 Initializes the decompression dictionary from the given uncompressed byte
567 sequence. This function must be called immediately after a call of inflate 634 sequence. This function must be called immediately after a call of inflate,
568 if this call returned Z_NEED_DICT. The dictionary chosen by the compressor 635 if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
569 can be determined from the Adler32 value returned by this call of 636 can be determined from the adler32 value returned by that call of inflate.
570 inflate. The compressor and decompressor must use exactly the same 637 The compressor and decompressor must use exactly the same dictionary (see
571 dictionary (see deflateSetDictionary). 638 deflateSetDictionary). For raw inflate, this function can be called
639 immediately after inflateInit2() or inflateReset() and before any call of
640 inflate() to set the dictionary. The application must insure that the
641 dictionary that was used for compression is provided.
572 642
573 inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a 643 inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
574 parameter is invalid (such as NULL dictionary) or the stream state is 644 parameter is invalid (such as NULL dictionary) or the stream state is
575 inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the 645 inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
576 expected one (incorrect Adler32 value). inflateSetDictionary does not 646 expected one (incorrect adler32 value). inflateSetDictionary does not
577 perform any decompression: this will be done by subsequent calls of 647 perform any decompression: this will be done by subsequent calls of
578 inflate(). 648 inflate().
579*/ 649*/
@@ -614,40 +684,19 @@ extern int zlib_inflateIncomp (z_stream *strm);
614 containing the data at next_in (except that the data is not output). 684 containing the data at next_in (except that the data is not output).
615*/ 685*/
616 686
617 /* various hacks, don't look :) */
618
619/* deflateInit and inflateInit are macros to allow checking the zlib version
620 * and the compiler's view of z_stream:
621 */
622extern int zlib_deflateInit_ (z_streamp strm, int level,
623 const char *version, int stream_size);
624extern int zlib_inflateInit_ (z_streamp strm,
625 const char *version, int stream_size);
626extern int zlib_deflateInit2_ (z_streamp strm, int level, int method,
627 int windowBits, int memLevel,
628 int strategy, const char *version,
629 int stream_size);
630extern int zlib_inflateInit2_ (z_streamp strm, int windowBits,
631 const char *version, int stream_size);
632#define zlib_deflateInit(strm, level) \ 687#define zlib_deflateInit(strm, level) \
633 zlib_deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) 688 zlib_deflateInit2((strm), (level), Z_DEFLATED, MAX_WBITS, \
689 DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY)
634#define zlib_inflateInit(strm) \ 690#define zlib_inflateInit(strm) \
635 zlib_inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) 691 zlib_inflateInit2((strm), DEF_WBITS)
636#define zlib_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
637 zlib_deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
638 (strategy), ZLIB_VERSION, sizeof(z_stream))
639#define zlib_inflateInit2(strm, windowBits) \
640 zlib_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
641 692
693extern int zlib_deflateInit2(z_streamp strm, int level, int method,
694 int windowBits, int memLevel,
695 int strategy);
696extern int zlib_inflateInit2(z_streamp strm, int windowBits);
642 697
643#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) 698#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
644 struct internal_state {int dummy;}; /* hack for buggy compilers */ 699 struct internal_state {int dummy;}; /* hack for buggy compilers */
645#endif 700#endif
646 701
647extern const char * zlib_zError (int err);
648#if 0
649extern int zlib_inflateSyncPoint (z_streamp z);
650#endif
651extern const uLong * zlib_get_crc_table (void);
652
653#endif /* _ZLIB_H */ 702#endif /* _ZLIB_H */
diff --git a/include/linux/zutil.h b/include/linux/zutil.h
index ee0c59cf2136..6adfa9a6ffe9 100644
--- a/include/linux/zutil.h
+++ b/include/linux/zutil.h
@@ -23,18 +23,6 @@ typedef unsigned long ulg;
23 23
24 /* common constants */ 24 /* common constants */
25 25
26#ifndef DEF_WBITS
27# define DEF_WBITS MAX_WBITS
28#endif
29/* default windowBits for decompression. MAX_WBITS is for compression only */
30
31#if MAX_MEM_LEVEL >= 8
32# define DEF_MEM_LEVEL 8
33#else
34# define DEF_MEM_LEVEL MAX_MEM_LEVEL
35#endif
36/* default memLevel */
37
38#define STORED_BLOCK 0 26#define STORED_BLOCK 0
39#define STATIC_TREES 1 27#define STATIC_TREES 1
40#define DYN_TREES 2 28#define DYN_TREES 2
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index b45a73712748..446afc3ea27f 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -378,6 +378,7 @@
378#define AC97_HAS_NO_MIC (1<<15) /* no MIC volume */ 378#define AC97_HAS_NO_MIC (1<<15) /* no MIC volume */
379#define AC97_HAS_NO_TONE (1<<16) /* no Tone volume */ 379#define AC97_HAS_NO_TONE (1<<16) /* no Tone volume */
380#define AC97_HAS_NO_STD_PCM (1<<17) /* no standard AC97 PCM volume and mute */ 380#define AC97_HAS_NO_STD_PCM (1<<17) /* no standard AC97 PCM volume and mute */
381#define AC97_HAS_NO_AUX (1<<18) /* no standard AC97 AUX volume and mute */
381 382
382/* rates indexes */ 383/* rates indexes */
383#define AC97_RATES_FRONT_DAC 0 384#define AC97_RATES_FRONT_DAC 0
diff --git a/include/sound/asequencer.h b/include/sound/asequencer.h
index 6691e4aa4ea7..3f2f4042a20d 100644
--- a/include/sound/asequencer.h
+++ b/include/sound/asequencer.h
@@ -605,6 +605,10 @@ struct snd_seq_remove_events {
605#define SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE (1<<11) /* Sampling device (support sample download) */ 605#define SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE (1<<11) /* Sampling device (support sample download) */
606#define SNDRV_SEQ_PORT_TYPE_SAMPLE (1<<12) /* Sampling device (sample can be downloaded at any time) */ 606#define SNDRV_SEQ_PORT_TYPE_SAMPLE (1<<12) /* Sampling device (sample can be downloaded at any time) */
607/*...*/ 607/*...*/
608#define SNDRV_SEQ_PORT_TYPE_HARDWARE (1<<16) /* driver for a hardware device */
609#define SNDRV_SEQ_PORT_TYPE_SOFTWARE (1<<17) /* implemented in software */
610#define SNDRV_SEQ_PORT_TYPE_SYNTHESIZER (1<<18) /* generates sound */
611#define SNDRV_SEQ_PORT_TYPE_PORT (1<<19) /* connects to other device(s) */
608#define SNDRV_SEQ_PORT_TYPE_APPLICATION (1<<20) /* application (sequencer/editor) */ 612#define SNDRV_SEQ_PORT_TYPE_APPLICATION (1<<20) /* application (sequencer/editor) */
609 613
610/* misc. conditioning flags */ 614/* misc. conditioning flags */
diff --git a/include/sound/asound.h b/include/sound/asound.h
index 9cc021c7ee11..41885f48ad91 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -137,7 +137,7 @@ enum {
137 * * 137 * *
138 *****************************************************************************/ 138 *****************************************************************************/
139 139
140#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7) 140#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 8)
141 141
142typedef unsigned long snd_pcm_uframes_t; 142typedef unsigned long snd_pcm_uframes_t;
143typedef signed long snd_pcm_sframes_t; 143typedef signed long snd_pcm_sframes_t;
diff --git a/include/sound/core.h b/include/sound/core.h
index 5135147f20e8..5d184be0ff72 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -233,9 +233,8 @@ int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size
233 233
234/* init.c */ 234/* init.c */
235 235
236extern unsigned int snd_cards_lock;
237extern struct snd_card *snd_cards[SNDRV_CARDS]; 236extern struct snd_card *snd_cards[SNDRV_CARDS];
238extern rwlock_t snd_card_rwlock; 237int snd_card_locked(int card);
239#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 238#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
240#define SND_MIXER_OSS_NOTIFY_REGISTER 0 239#define SND_MIXER_OSS_NOTIFY_REGISTER 0
241#define SND_MIXER_OSS_NOTIFY_DISCONNECT 1 240#define SND_MIXER_OSS_NOTIFY_DISCONNECT 1
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 186e00ad9e79..884bbf54cd36 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -245,6 +245,7 @@
245#define A_IOCFG_GPOUT0 0x0044 /* analog/digital */ 245#define A_IOCFG_GPOUT0 0x0044 /* analog/digital */
246#define A_IOCFG_DISABLE_ANALOG 0x0040 /* = 'enable' for Audigy2 (chiprev=4) */ 246#define A_IOCFG_DISABLE_ANALOG 0x0040 /* = 'enable' for Audigy2 (chiprev=4) */
247#define A_IOCFG_ENABLE_DIGITAL 0x0004 247#define A_IOCFG_ENABLE_DIGITAL 0x0004
248#define A_IOCFG_ENABLE_DIGITAL_AUDIGY4 0x0080
248#define A_IOCFG_UNKNOWN_20 0x0020 249#define A_IOCFG_UNKNOWN_20 0x0020
249#define A_IOCFG_DISABLE_AC97_FRONT 0x0080 /* turn off ac97 front -> front (10k2.1) */ 250#define A_IOCFG_DISABLE_AC97_FRONT 0x0080 /* turn off ac97 front -> front (10k2.1) */
250#define A_IOCFG_GPOUT1 0x0002 /* IR? drive's internal bypass (?) */ 251#define A_IOCFG_GPOUT1 0x0002 /* IR? drive's internal bypass (?) */
@@ -1065,6 +1066,7 @@ struct snd_emu_chip_details {
1065 unsigned char emu1212m; /* EMU 1212m card */ 1066 unsigned char emu1212m; /* EMU 1212m card */
1066 unsigned char spi_dac; /* SPI interface for DAC */ 1067 unsigned char spi_dac; /* SPI interface for DAC */
1067 unsigned char i2c_adc; /* I2C interface for ADC */ 1068 unsigned char i2c_adc; /* I2C interface for ADC */
1069 unsigned char adc_1361t; /* Use Philips 1361T ADC */
1068 const char *driver; 1070 const char *driver;
1069 const char *name; 1071 const char *name;
1070 const char *id; /* for backward compatibility - can be NULL if not needed */ 1072 const char *id; /* for backward compatibility - can be NULL if not needed */
diff --git a/include/sound/info.h b/include/sound/info.h
index f23d8381c216..74f6996769c7 100644
--- a/include/sound/info.h
+++ b/include/sound/info.h
@@ -27,9 +27,9 @@
27/* buffer for information */ 27/* buffer for information */
28struct snd_info_buffer { 28struct snd_info_buffer {
29 char *buffer; /* pointer to begin of buffer */ 29 char *buffer; /* pointer to begin of buffer */
30 char *curr; /* current position in buffer */ 30 unsigned int curr; /* current position in buffer */
31 unsigned long size; /* current size */ 31 unsigned int size; /* current size */
32 unsigned long len; /* total length of buffer */ 32 unsigned int len; /* total length of buffer */
33 int stop; /* stop flag */ 33 int stop; /* stop flag */
34 int error; /* error code */ 34 int error; /* error code */
35}; 35};
@@ -40,8 +40,6 @@ struct snd_info_buffer {
40struct snd_info_entry; 40struct snd_info_entry;
41 41
42struct snd_info_entry_text { 42struct snd_info_entry_text {
43 unsigned long read_size;
44 unsigned long write_size;
45 void (*read) (struct snd_info_entry *entry, struct snd_info_buffer *buffer); 43 void (*read) (struct snd_info_entry *entry, struct snd_info_buffer *buffer);
46 void (*write) (struct snd_info_entry *entry, struct snd_info_buffer *buffer); 44 void (*write) (struct snd_info_entry *entry, struct snd_info_buffer *buffer);
47}; 45};
@@ -132,11 +130,9 @@ int snd_card_proc_new(struct snd_card *card, const char *name, struct snd_info_e
132 130
133static inline void snd_info_set_text_ops(struct snd_info_entry *entry, 131static inline void snd_info_set_text_ops(struct snd_info_entry *entry,
134 void *private_data, 132 void *private_data,
135 long read_size,
136 void (*read)(struct snd_info_entry *, struct snd_info_buffer *)) 133 void (*read)(struct snd_info_entry *, struct snd_info_buffer *))
137{ 134{
138 entry->private_data = private_data; 135 entry->private_data = private_data;
139 entry->c.text.read_size = read_size;
140 entry->c.text.read = read; 136 entry->c.text.read = read;
141} 137}
142 138
@@ -167,7 +163,6 @@ static inline int snd_card_proc_new(struct snd_card *card, const char *name,
167 struct snd_info_entry **entryp) { return -EINVAL; } 163 struct snd_info_entry **entryp) { return -EINVAL; }
168static inline void snd_info_set_text_ops(struct snd_info_entry *entry __attribute__((unused)), 164static inline void snd_info_set_text_ops(struct snd_info_entry *entry __attribute__((unused)),
169 void *private_data, 165 void *private_data,
170 long read_size,
171 void (*read)(struct snd_info_entry *, struct snd_info_buffer *)) {} 166 void (*read)(struct snd_info_entry *, struct snd_info_buffer *)) {}
172 167
173static inline int snd_info_check_reserved_words(const char *str) { return 1; } 168static inline int snd_info_check_reserved_words(const char *str) { return 1; }
diff --git a/include/sound/mpu401.h b/include/sound/mpu401.h
index 8e97ace78f16..ac504321ea56 100644
--- a/include/sound/mpu401.h
+++ b/include/sound/mpu401.h
@@ -45,6 +45,12 @@
45#define MPU401_HW_PC98II 18 /* Roland PC98II */ 45#define MPU401_HW_PC98II 18 /* Roland PC98II */
46#define MPU401_HW_AUREAL 19 /* Aureal Vortex */ 46#define MPU401_HW_AUREAL 19 /* Aureal Vortex */
47 47
48#define MPU401_INFO_INPUT (1 << 0) /* input stream */
49#define MPU401_INFO_OUTPUT (1 << 1) /* output stream */
50#define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */
51#define MPU401_INFO_MMIO (1 << 3) /* MMIO access */
52#define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */
53
48#define MPU401_MODE_BIT_INPUT 0 54#define MPU401_MODE_BIT_INPUT 0
49#define MPU401_MODE_BIT_OUTPUT 1 55#define MPU401_MODE_BIT_OUTPUT 1
50#define MPU401_MODE_BIT_INPUT_TRIGGER 2 56#define MPU401_MODE_BIT_INPUT_TRIGGER 2
@@ -62,6 +68,7 @@ struct snd_mpu401 {
62 struct snd_rawmidi *rmidi; 68 struct snd_rawmidi *rmidi;
63 69
64 unsigned short hardware; /* MPU401_HW_XXXX */ 70 unsigned short hardware; /* MPU401_HW_XXXX */
71 unsigned int info_flags; /* MPU401_INFO_XXX */
65 unsigned long port; /* base port of MPU-401 chip */ 72 unsigned long port; /* base port of MPU-401 chip */
66 unsigned long cport; /* port + 1 (usually) */ 73 unsigned long cport; /* port + 1 (usually) */
67 struct resource *res; /* port resource */ 74 struct resource *res; /* port resource */
@@ -99,13 +106,16 @@ struct snd_mpu401 {
99 106
100 */ 107 */
101 108
102irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs); 109irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id,
110 struct pt_regs *regs);
111irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id,
112 struct pt_regs *regs);
103 113
104int snd_mpu401_uart_new(struct snd_card *card, 114int snd_mpu401_uart_new(struct snd_card *card,
105 int device, 115 int device,
106 unsigned short hardware, 116 unsigned short hardware,
107 unsigned long port, 117 unsigned long port,
108 int integrated, 118 unsigned int info_flags,
109 int irq, 119 int irq,
110 int irq_flags, 120 int irq_flags,
111 struct snd_rawmidi ** rrawmidi); 121 struct snd_rawmidi ** rrawmidi);
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 373425895faa..f84d84993a31 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -300,7 +300,6 @@ struct snd_pcm_runtime {
300 /* -- mmap -- */ 300 /* -- mmap -- */
301 volatile struct snd_pcm_mmap_status *status; 301 volatile struct snd_pcm_mmap_status *status;
302 volatile struct snd_pcm_mmap_control *control; 302 volatile struct snd_pcm_mmap_control *control;
303 atomic_t mmap_count;
304 303
305 /* -- locking / scheduling -- */ 304 /* -- locking / scheduling -- */
306 wait_queue_head_t sleep; 305 wait_queue_head_t sleep;
@@ -368,7 +367,9 @@ struct snd_pcm_substream {
368 struct snd_pcm_group *group; /* pointer to current group */ 367 struct snd_pcm_group *group; /* pointer to current group */
369 /* -- assigned files -- */ 368 /* -- assigned files -- */
370 void *file; 369 void *file;
371 struct file *ffile; 370 int ref_count;
371 atomic_t mmap_count;
372 unsigned int f_flags;
372 void (*pcm_release)(struct snd_pcm_substream *); 373 void (*pcm_release)(struct snd_pcm_substream *);
373#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 374#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
374 /* -- OSS things -- */ 375 /* -- OSS things -- */
@@ -387,7 +388,7 @@ struct snd_pcm_substream {
387 unsigned int hw_opened: 1; 388 unsigned int hw_opened: 1;
388}; 389};
389 390
390#define SUBSTREAM_BUSY(substream) ((substream)->file != NULL) 391#define SUBSTREAM_BUSY(substream) ((substream)->ref_count > 0)
391 392
392 393
393struct snd_pcm_str { 394struct snd_pcm_str {
@@ -825,14 +826,6 @@ int snd_interval_ratnum(struct snd_interval *i,
825 826
826void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params); 827void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params);
827void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var); 828void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var);
828int snd_pcm_hw_param_near(struct snd_pcm_substream *substream,
829 struct snd_pcm_hw_params *params,
830 snd_pcm_hw_param_t var,
831 unsigned int val, int *dir);
832int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm,
833 struct snd_pcm_hw_params *params,
834 snd_pcm_hw_param_t var,
835 unsigned int val, int dir);
836int snd_pcm_hw_params_choose(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); 829int snd_pcm_hw_params_choose(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params);
837 830
838int snd_pcm_hw_refine(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); 831int snd_pcm_hw_refine(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params);
@@ -979,13 +972,13 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne
979static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area) 972static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
980{ 973{
981 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; 974 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data;
982 atomic_inc(&substream->runtime->mmap_count); 975 atomic_inc(&substream->mmap_count);
983} 976}
984 977
985static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area) 978static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area)
986{ 979{
987 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; 980 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data;
988 atomic_dec(&substream->runtime->mmap_count); 981 atomic_dec(&substream->mmap_count);
989} 982}
990 983
991/* mmap for io-memory area */ 984/* mmap for io-memory area */
diff --git a/include/sound/pcm_params.h b/include/sound/pcm_params.h
index fb18aef77341..85cf1cf4f31a 100644
--- a/include/sound/pcm_params.h
+++ b/include/sound/pcm_params.h
@@ -22,29 +22,21 @@
22 * 22 *
23 */ 23 */
24 24
25extern int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params, 25int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm,
26 snd_pcm_hw_param_t var, const struct snd_mask *val); 26 struct snd_pcm_hw_params *params,
27extern unsigned int snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params, 27 snd_pcm_hw_param_t var, int *dir);
28 snd_pcm_hw_param_t var, int *dir); 28int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
29extern unsigned int snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params, 29 struct snd_pcm_hw_params *params,
30 snd_pcm_hw_param_t var, int *dir); 30 snd_pcm_hw_param_t var, int *dir);
31extern int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, 31int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
32 snd_pcm_hw_param_t var, unsigned int val, int dir); 32 snd_pcm_hw_param_t var, int *dir);
33extern int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params,
34 snd_pcm_hw_param_t var);
35extern int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
36 snd_pcm_hw_param_t var, unsigned int val, int dir);
37
38/* To share the same code we have alsa-lib */
39#define INLINE static inline
40#define assert(a) (void)(a)
41 33
42#define SNDRV_MASK_BITS 64 /* we use so far 64bits only */ 34#define SNDRV_MASK_BITS 64 /* we use so far 64bits only */
43#define SNDRV_MASK_SIZE (SNDRV_MASK_BITS / 32) 35#define SNDRV_MASK_SIZE (SNDRV_MASK_BITS / 32)
44#define MASK_OFS(i) ((i) >> 5) 36#define MASK_OFS(i) ((i) >> 5)
45#define MASK_BIT(i) (1U << ((i) & 31)) 37#define MASK_BIT(i) (1U << ((i) & 31))
46 38
47INLINE unsigned int ld2(u_int32_t v) 39static inline unsigned int ld2(u_int32_t v)
48{ 40{
49 unsigned r = 0; 41 unsigned r = 0;
50 42
@@ -69,22 +61,22 @@ INLINE unsigned int ld2(u_int32_t v)
69 return r; 61 return r;
70} 62}
71 63
72INLINE size_t snd_mask_sizeof(void) 64static inline size_t snd_mask_sizeof(void)
73{ 65{
74 return sizeof(struct snd_mask); 66 return sizeof(struct snd_mask);
75} 67}
76 68
77INLINE void snd_mask_none(struct snd_mask *mask) 69static inline void snd_mask_none(struct snd_mask *mask)
78{ 70{
79 memset(mask, 0, sizeof(*mask)); 71 memset(mask, 0, sizeof(*mask));
80} 72}
81 73
82INLINE void snd_mask_any(struct snd_mask *mask) 74static inline void snd_mask_any(struct snd_mask *mask)
83{ 75{
84 memset(mask, 0xff, SNDRV_MASK_SIZE * sizeof(u_int32_t)); 76 memset(mask, 0xff, SNDRV_MASK_SIZE * sizeof(u_int32_t));
85} 77}
86 78
87INLINE int snd_mask_empty(const struct snd_mask *mask) 79static inline int snd_mask_empty(const struct snd_mask *mask)
88{ 80{
89 int i; 81 int i;
90 for (i = 0; i < SNDRV_MASK_SIZE; i++) 82 for (i = 0; i < SNDRV_MASK_SIZE; i++)
@@ -93,10 +85,9 @@ INLINE int snd_mask_empty(const struct snd_mask *mask)
93 return 1; 85 return 1;
94} 86}
95 87
96INLINE unsigned int snd_mask_min(const struct snd_mask *mask) 88static inline unsigned int snd_mask_min(const struct snd_mask *mask)
97{ 89{
98 int i; 90 int i;
99 assert(!snd_mask_empty(mask));
100 for (i = 0; i < SNDRV_MASK_SIZE; i++) { 91 for (i = 0; i < SNDRV_MASK_SIZE; i++) {
101 if (mask->bits[i]) 92 if (mask->bits[i])
102 return ffs(mask->bits[i]) - 1 + (i << 5); 93 return ffs(mask->bits[i]) - 1 + (i << 5);
@@ -104,10 +95,9 @@ INLINE unsigned int snd_mask_min(const struct snd_mask *mask)
104 return 0; 95 return 0;
105} 96}
106 97
107INLINE unsigned int snd_mask_max(const struct snd_mask *mask) 98static inline unsigned int snd_mask_max(const struct snd_mask *mask)
108{ 99{
109 int i; 100 int i;
110 assert(!snd_mask_empty(mask));
111 for (i = SNDRV_MASK_SIZE - 1; i >= 0; i--) { 101 for (i = SNDRV_MASK_SIZE - 1; i >= 0; i--) {
112 if (mask->bits[i]) 102 if (mask->bits[i])
113 return ld2(mask->bits[i]) + (i << 5); 103 return ld2(mask->bits[i]) + (i << 5);
@@ -115,70 +105,68 @@ INLINE unsigned int snd_mask_max(const struct snd_mask *mask)
115 return 0; 105 return 0;
116} 106}
117 107
118INLINE void snd_mask_set(struct snd_mask *mask, unsigned int val) 108static inline void snd_mask_set(struct snd_mask *mask, unsigned int val)
119{ 109{
120 assert(val <= SNDRV_MASK_BITS);
121 mask->bits[MASK_OFS(val)] |= MASK_BIT(val); 110 mask->bits[MASK_OFS(val)] |= MASK_BIT(val);
122} 111}
123 112
124INLINE void snd_mask_reset(struct snd_mask *mask, unsigned int val) 113static inline void snd_mask_reset(struct snd_mask *mask, unsigned int val)
125{ 114{
126 assert(val <= SNDRV_MASK_BITS);
127 mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val); 115 mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val);
128} 116}
129 117
130INLINE void snd_mask_set_range(struct snd_mask *mask, unsigned int from, unsigned int to) 118static inline void snd_mask_set_range(struct snd_mask *mask,
119 unsigned int from, unsigned int to)
131{ 120{
132 unsigned int i; 121 unsigned int i;
133 assert(to <= SNDRV_MASK_BITS && from <= to);
134 for (i = from; i <= to; i++) 122 for (i = from; i <= to; i++)
135 mask->bits[MASK_OFS(i)] |= MASK_BIT(i); 123 mask->bits[MASK_OFS(i)] |= MASK_BIT(i);
136} 124}
137 125
138INLINE void snd_mask_reset_range(struct snd_mask *mask, unsigned int from, unsigned int to) 126static inline void snd_mask_reset_range(struct snd_mask *mask,
127 unsigned int from, unsigned int to)
139{ 128{
140 unsigned int i; 129 unsigned int i;
141 assert(to <= SNDRV_MASK_BITS && from <= to);
142 for (i = from; i <= to; i++) 130 for (i = from; i <= to; i++)
143 mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i); 131 mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i);
144} 132}
145 133
146INLINE void snd_mask_leave(struct snd_mask *mask, unsigned int val) 134static inline void snd_mask_leave(struct snd_mask *mask, unsigned int val)
147{ 135{
148 unsigned int v; 136 unsigned int v;
149 assert(val <= SNDRV_MASK_BITS);
150 v = mask->bits[MASK_OFS(val)] & MASK_BIT(val); 137 v = mask->bits[MASK_OFS(val)] & MASK_BIT(val);
151 snd_mask_none(mask); 138 snd_mask_none(mask);
152 mask->bits[MASK_OFS(val)] = v; 139 mask->bits[MASK_OFS(val)] = v;
153} 140}
154 141
155INLINE void snd_mask_intersect(struct snd_mask *mask, const struct snd_mask *v) 142static inline void snd_mask_intersect(struct snd_mask *mask,
143 const struct snd_mask *v)
156{ 144{
157 int i; 145 int i;
158 for (i = 0; i < SNDRV_MASK_SIZE; i++) 146 for (i = 0; i < SNDRV_MASK_SIZE; i++)
159 mask->bits[i] &= v->bits[i]; 147 mask->bits[i] &= v->bits[i];
160} 148}
161 149
162INLINE int snd_mask_eq(const struct snd_mask *mask, const struct snd_mask *v) 150static inline int snd_mask_eq(const struct snd_mask *mask,
151 const struct snd_mask *v)
163{ 152{
164 return ! memcmp(mask, v, SNDRV_MASK_SIZE * sizeof(u_int32_t)); 153 return ! memcmp(mask, v, SNDRV_MASK_SIZE * sizeof(u_int32_t));
165} 154}
166 155
167INLINE void snd_mask_copy(struct snd_mask *mask, const struct snd_mask *v) 156static inline void snd_mask_copy(struct snd_mask *mask,
157 const struct snd_mask *v)
168{ 158{
169 *mask = *v; 159 *mask = *v;
170} 160}
171 161
172INLINE int snd_mask_test(const struct snd_mask *mask, unsigned int val) 162static inline int snd_mask_test(const struct snd_mask *mask, unsigned int val)
173{ 163{
174 assert(val <= SNDRV_MASK_BITS);
175 return mask->bits[MASK_OFS(val)] & MASK_BIT(val); 164 return mask->bits[MASK_OFS(val)] & MASK_BIT(val);
176} 165}
177 166
178INLINE int snd_mask_single(const struct snd_mask *mask) 167static inline int snd_mask_single(const struct snd_mask *mask)
179{ 168{
180 int i, c = 0; 169 int i, c = 0;
181 assert(!snd_mask_empty(mask));
182 for (i = 0; i < SNDRV_MASK_SIZE; i++) { 170 for (i = 0; i < SNDRV_MASK_SIZE; i++) {
183 if (! mask->bits[i]) 171 if (! mask->bits[i])
184 continue; 172 continue;
@@ -191,10 +179,10 @@ INLINE int snd_mask_single(const struct snd_mask *mask)
191 return 1; 179 return 1;
192} 180}
193 181
194INLINE int snd_mask_refine(struct snd_mask *mask, const struct snd_mask *v) 182static inline int snd_mask_refine(struct snd_mask *mask,
183 const struct snd_mask *v)
195{ 184{
196 struct snd_mask old; 185 struct snd_mask old;
197 assert(!snd_mask_empty(mask));
198 snd_mask_copy(&old, mask); 186 snd_mask_copy(&old, mask);
199 snd_mask_intersect(mask, v); 187 snd_mask_intersect(mask, v);
200 if (snd_mask_empty(mask)) 188 if (snd_mask_empty(mask))
@@ -202,27 +190,24 @@ INLINE int snd_mask_refine(struct snd_mask *mask, const struct snd_mask *v)
202 return !snd_mask_eq(mask, &old); 190 return !snd_mask_eq(mask, &old);
203} 191}
204 192
205INLINE int snd_mask_refine_first(struct snd_mask *mask) 193static inline int snd_mask_refine_first(struct snd_mask *mask)
206{ 194{
207 assert(!snd_mask_empty(mask));
208 if (snd_mask_single(mask)) 195 if (snd_mask_single(mask))
209 return 0; 196 return 0;
210 snd_mask_leave(mask, snd_mask_min(mask)); 197 snd_mask_leave(mask, snd_mask_min(mask));
211 return 1; 198 return 1;
212} 199}
213 200
214INLINE int snd_mask_refine_last(struct snd_mask *mask) 201static inline int snd_mask_refine_last(struct snd_mask *mask)
215{ 202{
216 assert(!snd_mask_empty(mask));
217 if (snd_mask_single(mask)) 203 if (snd_mask_single(mask))
218 return 0; 204 return 0;
219 snd_mask_leave(mask, snd_mask_max(mask)); 205 snd_mask_leave(mask, snd_mask_max(mask));
220 return 1; 206 return 1;
221} 207}
222 208
223INLINE int snd_mask_refine_min(struct snd_mask *mask, unsigned int val) 209static inline int snd_mask_refine_min(struct snd_mask *mask, unsigned int val)
224{ 210{
225 assert(!snd_mask_empty(mask));
226 if (snd_mask_min(mask) >= val) 211 if (snd_mask_min(mask) >= val)
227 return 0; 212 return 0;
228 snd_mask_reset_range(mask, 0, val - 1); 213 snd_mask_reset_range(mask, 0, val - 1);
@@ -231,9 +216,8 @@ INLINE int snd_mask_refine_min(struct snd_mask *mask, unsigned int val)
231 return 1; 216 return 1;
232} 217}
233 218
234INLINE int snd_mask_refine_max(struct snd_mask *mask, unsigned int val) 219static inline int snd_mask_refine_max(struct snd_mask *mask, unsigned int val)
235{ 220{
236 assert(!snd_mask_empty(mask));
237 if (snd_mask_max(mask) <= val) 221 if (snd_mask_max(mask) <= val)
238 return 0; 222 return 0;
239 snd_mask_reset_range(mask, val + 1, SNDRV_MASK_BITS); 223 snd_mask_reset_range(mask, val + 1, SNDRV_MASK_BITS);
@@ -242,10 +226,9 @@ INLINE int snd_mask_refine_max(struct snd_mask *mask, unsigned int val)
242 return 1; 226 return 1;
243} 227}
244 228
245INLINE int snd_mask_refine_set(struct snd_mask *mask, unsigned int val) 229static inline int snd_mask_refine_set(struct snd_mask *mask, unsigned int val)
246{ 230{
247 int changed; 231 int changed;
248 assert(!snd_mask_empty(mask));
249 changed = !snd_mask_single(mask); 232 changed = !snd_mask_single(mask);
250 snd_mask_leave(mask, val); 233 snd_mask_leave(mask, val);
251 if (snd_mask_empty(mask)) 234 if (snd_mask_empty(mask))
@@ -253,13 +236,12 @@ INLINE int snd_mask_refine_set(struct snd_mask *mask, unsigned int val)
253 return changed; 236 return changed;
254} 237}
255 238
256INLINE int snd_mask_value(const struct snd_mask *mask) 239static inline int snd_mask_value(const struct snd_mask *mask)
257{ 240{
258 assert(!snd_mask_empty(mask));
259 return snd_mask_min(mask); 241 return snd_mask_min(mask);
260} 242}
261 243
262INLINE void snd_interval_any(struct snd_interval *i) 244static inline void snd_interval_any(struct snd_interval *i)
263{ 245{
264 i->min = 0; 246 i->min = 0;
265 i->openmin = 0; 247 i->openmin = 0;
@@ -269,63 +251,59 @@ INLINE void snd_interval_any(struct snd_interval *i)
269 i->empty = 0; 251 i->empty = 0;
270} 252}
271 253
272INLINE void snd_interval_none(struct snd_interval *i) 254static inline void snd_interval_none(struct snd_interval *i)
273{ 255{
274 i->empty = 1; 256 i->empty = 1;
275} 257}
276 258
277INLINE int snd_interval_checkempty(const struct snd_interval *i) 259static inline int snd_interval_checkempty(const struct snd_interval *i)
278{ 260{
279 return (i->min > i->max || 261 return (i->min > i->max ||
280 (i->min == i->max && (i->openmin || i->openmax))); 262 (i->min == i->max && (i->openmin || i->openmax)));
281} 263}
282 264
283INLINE int snd_interval_empty(const struct snd_interval *i) 265static inline int snd_interval_empty(const struct snd_interval *i)
284{ 266{
285 return i->empty; 267 return i->empty;
286} 268}
287 269
288INLINE int snd_interval_single(const struct snd_interval *i) 270static inline int snd_interval_single(const struct snd_interval *i)
289{ 271{
290 assert(!snd_interval_empty(i));
291 return (i->min == i->max || 272 return (i->min == i->max ||
292 (i->min + 1 == i->max && i->openmax)); 273 (i->min + 1 == i->max && i->openmax));
293} 274}
294 275
295INLINE int snd_interval_value(const struct snd_interval *i) 276static inline int snd_interval_value(const struct snd_interval *i)
296{ 277{
297 assert(snd_interval_single(i));
298 return i->min; 278 return i->min;
299} 279}
300 280
301INLINE int snd_interval_min(const struct snd_interval *i) 281static inline int snd_interval_min(const struct snd_interval *i)
302{ 282{
303 assert(!snd_interval_empty(i));
304 return i->min; 283 return i->min;
305} 284}
306 285
307INLINE int snd_interval_max(const struct snd_interval *i) 286static inline int snd_interval_max(const struct snd_interval *i)
308{ 287{
309 unsigned int v; 288 unsigned int v;
310 assert(!snd_interval_empty(i));
311 v = i->max; 289 v = i->max;
312 if (i->openmax) 290 if (i->openmax)
313 v--; 291 v--;
314 return v; 292 return v;
315} 293}
316 294
317INLINE int snd_interval_test(const struct snd_interval *i, unsigned int val) 295static inline int snd_interval_test(const struct snd_interval *i, unsigned int val)
318{ 296{
319 return !((i->min > val || (i->min == val && i->openmin) || 297 return !((i->min > val || (i->min == val && i->openmin) ||
320 i->max < val || (i->max == val && i->openmax))); 298 i->max < val || (i->max == val && i->openmax)));
321} 299}
322 300
323INLINE void snd_interval_copy(struct snd_interval *d, const struct snd_interval *s) 301static inline void snd_interval_copy(struct snd_interval *d, const struct snd_interval *s)
324{ 302{
325 *d = *s; 303 *d = *s;
326} 304}
327 305
328INLINE int snd_interval_setinteger(struct snd_interval *i) 306static inline int snd_interval_setinteger(struct snd_interval *i)
329{ 307{
330 if (i->integer) 308 if (i->integer)
331 return 0; 309 return 0;
@@ -335,7 +313,7 @@ INLINE int snd_interval_setinteger(struct snd_interval *i)
335 return 1; 313 return 1;
336} 314}
337 315
338INLINE int snd_interval_eq(const struct snd_interval *i1, const struct snd_interval *i2) 316static inline int snd_interval_eq(const struct snd_interval *i1, const struct snd_interval *i2)
339{ 317{
340 if (i1->empty) 318 if (i1->empty)
341 return i2->empty; 319 return i2->empty;
@@ -359,8 +337,5 @@ static inline unsigned int sub(unsigned int a, unsigned int b)
359 return 0; 337 return 0;
360} 338}
361 339
362#undef INLINE
363#undef assert
364
365#endif /* __SOUND_PCM_PARAMS_H */ 340#endif /* __SOUND_PCM_PARAMS_H */
366 341
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index 584e73dd4793..7dbcd10fa215 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -46,6 +46,7 @@
46 46
47struct snd_rawmidi; 47struct snd_rawmidi;
48struct snd_rawmidi_substream; 48struct snd_rawmidi_substream;
49struct snd_seq_port_info;
49 50
50struct snd_rawmidi_ops { 51struct snd_rawmidi_ops {
51 int (*open) (struct snd_rawmidi_substream * substream); 52 int (*open) (struct snd_rawmidi_substream * substream);
@@ -57,6 +58,8 @@ struct snd_rawmidi_ops {
57struct snd_rawmidi_global_ops { 58struct snd_rawmidi_global_ops {
58 int (*dev_register) (struct snd_rawmidi * rmidi); 59 int (*dev_register) (struct snd_rawmidi * rmidi);
59 int (*dev_unregister) (struct snd_rawmidi * rmidi); 60 int (*dev_unregister) (struct snd_rawmidi * rmidi);
61 void (*get_port_info)(struct snd_rawmidi *rmidi, int number,
62 struct snd_seq_port_info *info);
60}; 63};
61 64
62struct snd_rawmidi_runtime { 65struct snd_rawmidi_runtime {
diff --git a/include/sound/version.h b/include/sound/version.h
index 4f0e65808cf1..2ee849d0e198 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
1/* include/version.h. Generated by configure. */ 1/* include/version.h. Generated by configure. */
2#define CONFIG_SND_VERSION "1.0.11rc4" 2#define CONFIG_SND_VERSION "1.0.12rc1"
3#define CONFIG_SND_DATE " (Wed Mar 22 10:27:24 2006 UTC)" 3#define CONFIG_SND_DATE " (Thu Jun 22 13:55:50 2006 UTC)"
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 0a907f0dc56b..cdf0f07af92f 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -15,7 +15,7 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/pm.h> 17#include <linux/pm.h>
18 18#include <linux/console.h>
19 19
20#include "power.h" 20#include "power.h"
21 21
diff --git a/kernel/sys.c b/kernel/sys.c
index 0b6ec0e7936f..fc9ebbbaba0c 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1860,23 +1860,20 @@ out:
1860 * fields when reaping, so a sample either gets all the additions of a 1860 * fields when reaping, so a sample either gets all the additions of a
1861 * given child after it's reaped, or none so this sample is before reaping. 1861 * given child after it's reaped, or none so this sample is before reaping.
1862 * 1862 *
1863 * tasklist_lock locking optimisation: 1863 * Locking:
1864 * If we are current and single threaded, we do not need to take the tasklist 1864 * We need to take the siglock for CHILDEREN, SELF and BOTH
1865 * lock or the siglock. No one else can take our signal_struct away, 1865 * for the cases current multithreaded, non-current single threaded
1866 * no one else can reap the children to update signal->c* counters, and 1866 * non-current multithreaded. Thread traversal is now safe with
1867 * no one else can race with the signal-> fields. 1867 * the siglock held.
1868 * If we do not take the tasklist_lock, the signal-> fields could be read 1868 * Strictly speaking, we donot need to take the siglock if we are current and
1869 * out of order while another thread was just exiting. So we place a 1869 * single threaded, as no one else can take our signal_struct away, no one
1870 * read memory barrier when we avoid the lock. On the writer side, 1870 * else can reap the children to update signal->c* counters, and no one else
1871 * write memory barrier is implied in __exit_signal as __exit_signal releases 1871 * can race with the signal-> fields. If we do not take any lock, the
1872 * the siglock spinlock after updating the signal-> fields. 1872 * signal-> fields could be read out of order while another thread was just
1873 * 1873 * exiting. So we should place a read memory barrier when we avoid the lock.
1874 * We don't really need the siglock when we access the non c* fields 1874 * On the writer side, write memory barrier is implied in __exit_signal
1875 * of the signal_struct (for RUSAGE_SELF) even in multithreaded 1875 * as __exit_signal releases the siglock spinlock after updating the signal->
1876 * case, since we take the tasklist lock for read and the non c* signal-> 1876 * fields. But we don't do this yet to keep things simple.
1877 * fields are updated only in __exit_signal, which is called with
1878 * tasklist_lock taken for write, hence these two threads cannot execute
1879 * concurrently.
1880 * 1877 *
1881 */ 1878 */
1882 1879
@@ -1885,35 +1882,25 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1885 struct task_struct *t; 1882 struct task_struct *t;
1886 unsigned long flags; 1883 unsigned long flags;
1887 cputime_t utime, stime; 1884 cputime_t utime, stime;
1888 int need_lock = 0;
1889 1885
1890 memset((char *) r, 0, sizeof *r); 1886 memset((char *) r, 0, sizeof *r);
1891 utime = stime = cputime_zero; 1887 utime = stime = cputime_zero;
1892 1888
1893 if (p != current || !thread_group_empty(p)) 1889 rcu_read_lock();
1894 need_lock = 1; 1890 if (!lock_task_sighand(p, &flags)) {
1895 1891 rcu_read_unlock();
1896 if (need_lock) { 1892 return;
1897 read_lock(&tasklist_lock); 1893 }
1898 if (unlikely(!p->signal)) {
1899 read_unlock(&tasklist_lock);
1900 return;
1901 }
1902 } else
1903 /* See locking comments above */
1904 smp_rmb();
1905 1894
1906 switch (who) { 1895 switch (who) {
1907 case RUSAGE_BOTH: 1896 case RUSAGE_BOTH:
1908 case RUSAGE_CHILDREN: 1897 case RUSAGE_CHILDREN:
1909 spin_lock_irqsave(&p->sighand->siglock, flags);
1910 utime = p->signal->cutime; 1898 utime = p->signal->cutime;
1911 stime = p->signal->cstime; 1899 stime = p->signal->cstime;
1912 r->ru_nvcsw = p->signal->cnvcsw; 1900 r->ru_nvcsw = p->signal->cnvcsw;
1913 r->ru_nivcsw = p->signal->cnivcsw; 1901 r->ru_nivcsw = p->signal->cnivcsw;
1914 r->ru_minflt = p->signal->cmin_flt; 1902 r->ru_minflt = p->signal->cmin_flt;
1915 r->ru_majflt = p->signal->cmaj_flt; 1903 r->ru_majflt = p->signal->cmaj_flt;
1916 spin_unlock_irqrestore(&p->sighand->siglock, flags);
1917 1904
1918 if (who == RUSAGE_CHILDREN) 1905 if (who == RUSAGE_CHILDREN)
1919 break; 1906 break;
@@ -1941,8 +1928,9 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1941 BUG(); 1928 BUG();
1942 } 1929 }
1943 1930
1944 if (need_lock) 1931 unlock_task_sighand(p, &flags);
1945 read_unlock(&tasklist_lock); 1932 rcu_read_unlock();
1933
1946 cputime_to_timeval(utime, &r->ru_utime); 1934 cputime_to_timeval(utime, &r->ru_utime);
1947 cputime_to_timeval(stime, &r->ru_stime); 1935 cputime_to_timeval(stime, &r->ru_stime);
1948} 1936}
diff --git a/kernel/user.c b/kernel/user.c
index 4b1eb745afa1..6408c0424291 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -148,7 +148,7 @@ struct user_struct * alloc_uid(uid_t uid)
148 new->mq_bytes = 0; 148 new->mq_bytes = 0;
149 new->locked_shm = 0; 149 new->locked_shm = 0;
150 150
151 if (alloc_uid_keyring(new) < 0) { 151 if (alloc_uid_keyring(new, current) < 0) {
152 kmem_cache_free(uid_cachep, new); 152 kmem_cache_free(uid_cachep, new);
153 return NULL; 153 return NULL;
154 } 154 }
diff --git a/lib/zlib_deflate/deflate.c b/lib/zlib_deflate/deflate.c
index 1653dd9bb01a..c3e4a2baf835 100644
--- a/lib/zlib_deflate/deflate.c
+++ b/lib/zlib_deflate/deflate.c
@@ -164,34 +164,17 @@ static const config configuration_table[10] = {
164 memset((char *)s->head, 0, (unsigned)(s->hash_size-1)*sizeof(*s->head)); 164 memset((char *)s->head, 0, (unsigned)(s->hash_size-1)*sizeof(*s->head));
165 165
166/* ========================================================================= */ 166/* ========================================================================= */
167int zlib_deflateInit_( 167int zlib_deflateInit2(
168 z_streamp strm,
169 int level,
170 const char *version,
171 int stream_size
172)
173{
174 return zlib_deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS,
175 DEF_MEM_LEVEL,
176 Z_DEFAULT_STRATEGY, version, stream_size);
177 /* To do: ignore strm->next_in if we use it as window */
178}
179
180/* ========================================================================= */
181int zlib_deflateInit2_(
182 z_streamp strm, 168 z_streamp strm,
183 int level, 169 int level,
184 int method, 170 int method,
185 int windowBits, 171 int windowBits,
186 int memLevel, 172 int memLevel,
187 int strategy, 173 int strategy
188 const char *version,
189 int stream_size
190) 174)
191{ 175{
192 deflate_state *s; 176 deflate_state *s;
193 int noheader = 0; 177 int noheader = 0;
194 static char* my_version = ZLIB_VERSION;
195 deflate_workspace *mem; 178 deflate_workspace *mem;
196 179
197 ush *overlay; 180 ush *overlay;
@@ -199,10 +182,6 @@ int zlib_deflateInit2_(
199 * output size for (length,distance) codes is <= 24 bits. 182 * output size for (length,distance) codes is <= 24 bits.
200 */ 183 */
201 184
202 if (version == NULL || version[0] != my_version[0] ||
203 stream_size != sizeof(z_stream)) {
204 return Z_VERSION_ERROR;
205 }
206 if (strm == NULL) return Z_STREAM_ERROR; 185 if (strm == NULL) return Z_STREAM_ERROR;
207 186
208 strm->msg = NULL; 187 strm->msg = NULL;
diff --git a/lib/zlib_deflate/deflate_syms.c b/lib/zlib_deflate/deflate_syms.c
index 767b573d1ef6..ccfe25f3920f 100644
--- a/lib/zlib_deflate/deflate_syms.c
+++ b/lib/zlib_deflate/deflate_syms.c
@@ -12,8 +12,7 @@
12 12
13EXPORT_SYMBOL(zlib_deflate_workspacesize); 13EXPORT_SYMBOL(zlib_deflate_workspacesize);
14EXPORT_SYMBOL(zlib_deflate); 14EXPORT_SYMBOL(zlib_deflate);
15EXPORT_SYMBOL(zlib_deflateInit_); 15EXPORT_SYMBOL(zlib_deflateInit2);
16EXPORT_SYMBOL(zlib_deflateInit2_);
17EXPORT_SYMBOL(zlib_deflateEnd); 16EXPORT_SYMBOL(zlib_deflateEnd);
18EXPORT_SYMBOL(zlib_deflateReset); 17EXPORT_SYMBOL(zlib_deflateReset);
19MODULE_LICENSE("GPL"); 18MODULE_LICENSE("GPL");
diff --git a/lib/zlib_inflate/Makefile b/lib/zlib_inflate/Makefile
index 221c139e0df1..bf065482fa67 100644
--- a/lib/zlib_inflate/Makefile
+++ b/lib/zlib_inflate/Makefile
@@ -15,5 +15,5 @@
15 15
16obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o 16obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o
17 17
18zlib_inflate-objs := infblock.o infcodes.o inffast.o inflate.o \ 18zlib_inflate-objs := inffast.o inflate.o \
19 inflate_sync.o inftrees.o infutil.o inflate_syms.o 19 inftrees.o inflate_syms.o
diff --git a/lib/zlib_inflate/infblock.c b/lib/zlib_inflate/infblock.c
deleted file mode 100644
index c16cdeff51aa..000000000000
--- a/lib/zlib_inflate/infblock.c
+++ /dev/null
@@ -1,365 +0,0 @@
1/* infblock.c -- interpret and process block types to last block
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include <linux/zutil.h>
7#include "infblock.h"
8#include "inftrees.h"
9#include "infcodes.h"
10#include "infutil.h"
11
12struct inflate_codes_state;
13
14/* simplify the use of the inflate_huft type with some defines */
15#define exop word.what.Exop
16#define bits word.what.Bits
17
18/* Table for deflate from PKZIP's appnote.txt. */
19static const uInt border[] = { /* Order of the bit length code lengths */
20 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
21
22/*
23 Notes beyond the 1.93a appnote.txt:
24
25 1. Distance pointers never point before the beginning of the output
26 stream.
27 2. Distance pointers can point back across blocks, up to 32k away.
28 3. There is an implied maximum of 7 bits for the bit length table and
29 15 bits for the actual data.
30 4. If only one code exists, then it is encoded using one bit. (Zero
31 would be more efficient, but perhaps a little confusing.) If two
32 codes exist, they are coded using one bit each (0 and 1).
33 5. There is no way of sending zero distance codes--a dummy must be
34 sent if there are none. (History: a pre 2.0 version of PKZIP would
35 store blocks with no distance codes, but this was discovered to be
36 too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
37 zero distance codes, which is sent as one code of zero bits in
38 length.
39 6. There are up to 286 literal/length codes. Code 256 represents the
40 end-of-block. Note however that the static length tree defines
41 288 codes just to fill out the Huffman codes. Codes 286 and 287
42 cannot be used though, since there is no length base or extra bits
43 defined for them. Similarily, there are up to 30 distance codes.
44 However, static trees define 32 codes (all 5 bits) to fill out the
45 Huffman codes, but the last two had better not show up in the data.
46 7. Unzip can check dynamic Huffman blocks for complete code sets.
47 The exception is that a single code would not be complete (see #4).
48 8. The five bits following the block type is really the number of
49 literal codes sent minus 257.
50 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
51 (1+6+6). Therefore, to output three times the length, you output
52 three codes (1+1+1), whereas to output four times the same length,
53 you only need two codes (1+3). Hmm.
54 10. In the tree reconstruction algorithm, Code = Code + Increment
55 only if BitLength(i) is not zero. (Pretty obvious.)
56 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
57 12. Note: length code 284 can represent 227-258, but length code 285
58 really is 258. The last length deserves its own, short code
59 since it gets used a lot in very redundant files. The length
60 258 is special since 258 - 3 (the min match length) is 255.
61 13. The literal/length and distance code bit lengths are read as a
62 single stream of lengths. It is possible (and advantageous) for
63 a repeat code (16, 17, or 18) to go across the boundary between
64 the two sets of lengths.
65 */
66
67
68void zlib_inflate_blocks_reset(
69 inflate_blocks_statef *s,
70 z_streamp z,
71 uLong *c
72)
73{
74 if (c != NULL)
75 *c = s->check;
76 if (s->mode == CODES)
77 zlib_inflate_codes_free(s->sub.decode.codes, z);
78 s->mode = TYPE;
79 s->bitk = 0;
80 s->bitb = 0;
81 s->read = s->write = s->window;
82 if (s->checkfn != NULL)
83 z->adler = s->check = (*s->checkfn)(0L, NULL, 0);
84}
85
86inflate_blocks_statef *zlib_inflate_blocks_new(
87 z_streamp z,
88 check_func c,
89 uInt w
90)
91{
92 inflate_blocks_statef *s;
93
94 s = &WS(z)->working_blocks_state;
95 s->hufts = WS(z)->working_hufts;
96 s->window = WS(z)->working_window;
97 s->end = s->window + w;
98 s->checkfn = c;
99 s->mode = TYPE;
100 zlib_inflate_blocks_reset(s, z, NULL);
101 return s;
102}
103
104
105int zlib_inflate_blocks(
106 inflate_blocks_statef *s,
107 z_streamp z,
108 int r
109)
110{
111 uInt t; /* temporary storage */
112 uLong b; /* bit buffer */
113 uInt k; /* bits in bit buffer */
114 Byte *p; /* input data pointer */
115 uInt n; /* bytes available there */
116 Byte *q; /* output window write pointer */
117 uInt m; /* bytes to end of window or read pointer */
118
119 /* copy input/output information to locals (UPDATE macro restores) */
120 LOAD
121
122 /* process input based on current state */
123 while (1) switch (s->mode)
124 {
125 case TYPE:
126 NEEDBITS(3)
127 t = (uInt)b & 7;
128 s->last = t & 1;
129 switch (t >> 1)
130 {
131 case 0: /* stored */
132 DUMPBITS(3)
133 t = k & 7; /* go to byte boundary */
134 DUMPBITS(t)
135 s->mode = LENS; /* get length of stored block */
136 break;
137 case 1: /* fixed */
138 {
139 uInt bl, bd;
140 inflate_huft *tl, *td;
141
142 zlib_inflate_trees_fixed(&bl, &bd, &tl, &td, s->hufts, z);
143 s->sub.decode.codes = zlib_inflate_codes_new(bl, bd, tl, td, z);
144 if (s->sub.decode.codes == NULL)
145 {
146 r = Z_MEM_ERROR;
147 LEAVE
148 }
149 }
150 DUMPBITS(3)
151 s->mode = CODES;
152 break;
153 case 2: /* dynamic */
154 DUMPBITS(3)
155 s->mode = TABLE;
156 break;
157 case 3: /* illegal */
158 DUMPBITS(3)
159 s->mode = B_BAD;
160 z->msg = (char*)"invalid block type";
161 r = Z_DATA_ERROR;
162 LEAVE
163 }
164 break;
165 case LENS:
166 NEEDBITS(32)
167 if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
168 {
169 s->mode = B_BAD;
170 z->msg = (char*)"invalid stored block lengths";
171 r = Z_DATA_ERROR;
172 LEAVE
173 }
174 s->sub.left = (uInt)b & 0xffff;
175 b = k = 0; /* dump bits */
176 s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
177 break;
178 case STORED:
179 if (n == 0)
180 LEAVE
181 NEEDOUT
182 t = s->sub.left;
183 if (t > n) t = n;
184 if (t > m) t = m;
185 memcpy(q, p, t);
186 p += t; n -= t;
187 q += t; m -= t;
188 if ((s->sub.left -= t) != 0)
189 break;
190 s->mode = s->last ? DRY : TYPE;
191 break;
192 case TABLE:
193 NEEDBITS(14)
194 s->sub.trees.table = t = (uInt)b & 0x3fff;
195#ifndef PKZIP_BUG_WORKAROUND
196 if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
197 {
198 s->mode = B_BAD;
199 z->msg = (char*)"too many length or distance symbols";
200 r = Z_DATA_ERROR;
201 LEAVE
202 }
203#endif
204 {
205 s->sub.trees.blens = WS(z)->working_blens;
206 }
207 DUMPBITS(14)
208 s->sub.trees.index = 0;
209 s->mode = BTREE;
210 case BTREE:
211 while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
212 {
213 NEEDBITS(3)
214 s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
215 DUMPBITS(3)
216 }
217 while (s->sub.trees.index < 19)
218 s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
219 s->sub.trees.bb = 7;
220 t = zlib_inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
221 &s->sub.trees.tb, s->hufts, z);
222 if (t != Z_OK)
223 {
224 r = t;
225 if (r == Z_DATA_ERROR)
226 s->mode = B_BAD;
227 LEAVE
228 }
229 s->sub.trees.index = 0;
230 s->mode = DTREE;
231 case DTREE:
232 while (t = s->sub.trees.table,
233 s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
234 {
235 inflate_huft *h;
236 uInt i, j, c;
237
238 t = s->sub.trees.bb;
239 NEEDBITS(t)
240 h = s->sub.trees.tb + ((uInt)b & zlib_inflate_mask[t]);
241 t = h->bits;
242 c = h->base;
243 if (c < 16)
244 {
245 DUMPBITS(t)
246 s->sub.trees.blens[s->sub.trees.index++] = c;
247 }
248 else /* c == 16..18 */
249 {
250 i = c == 18 ? 7 : c - 14;
251 j = c == 18 ? 11 : 3;
252 NEEDBITS(t + i)
253 DUMPBITS(t)
254 j += (uInt)b & zlib_inflate_mask[i];
255 DUMPBITS(i)
256 i = s->sub.trees.index;
257 t = s->sub.trees.table;
258 if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
259 (c == 16 && i < 1))
260 {
261 s->mode = B_BAD;
262 z->msg = (char*)"invalid bit length repeat";
263 r = Z_DATA_ERROR;
264 LEAVE
265 }
266 c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
267 do {
268 s->sub.trees.blens[i++] = c;
269 } while (--j);
270 s->sub.trees.index = i;
271 }
272 }
273 s->sub.trees.tb = NULL;
274 {
275 uInt bl, bd;
276 inflate_huft *tl, *td;
277 inflate_codes_statef *c;
278
279 bl = 9; /* must be <= 9 for lookahead assumptions */
280 bd = 6; /* must be <= 9 for lookahead assumptions */
281 t = s->sub.trees.table;
282 t = zlib_inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
283 s->sub.trees.blens, &bl, &bd, &tl, &td,
284 s->hufts, z);
285 if (t != Z_OK)
286 {
287 if (t == (uInt)Z_DATA_ERROR)
288 s->mode = B_BAD;
289 r = t;
290 LEAVE
291 }
292 if ((c = zlib_inflate_codes_new(bl, bd, tl, td, z)) == NULL)
293 {
294 r = Z_MEM_ERROR;
295 LEAVE
296 }
297 s->sub.decode.codes = c;
298 }
299 s->mode = CODES;
300 case CODES:
301 UPDATE
302 if ((r = zlib_inflate_codes(s, z, r)) != Z_STREAM_END)
303 return zlib_inflate_flush(s, z, r);
304 r = Z_OK;
305 zlib_inflate_codes_free(s->sub.decode.codes, z);
306 LOAD
307 if (!s->last)
308 {
309 s->mode = TYPE;
310 break;
311 }
312 s->mode = DRY;
313 case DRY:
314 FLUSH
315 if (s->read != s->write)
316 LEAVE
317 s->mode = B_DONE;
318 case B_DONE:
319 r = Z_STREAM_END;
320 LEAVE
321 case B_BAD:
322 r = Z_DATA_ERROR;
323 LEAVE
324 default:
325 r = Z_STREAM_ERROR;
326 LEAVE
327 }
328}
329
330
331int zlib_inflate_blocks_free(
332 inflate_blocks_statef *s,
333 z_streamp z
334)
335{
336 zlib_inflate_blocks_reset(s, z, NULL);
337 return Z_OK;
338}
339
340
341#if 0
342void zlib_inflate_set_dictionary(
343 inflate_blocks_statef *s,
344 const Byte *d,
345 uInt n
346)
347{
348 memcpy(s->window, d, n);
349 s->read = s->write = s->window + n;
350}
351#endif /* 0 */
352
353
354/* Returns true if inflate is currently at the end of a block generated
355 * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
356 * IN assertion: s != NULL
357 */
358#if 0
359int zlib_inflate_blocks_sync_point(
360 inflate_blocks_statef *s
361)
362{
363 return s->mode == LENS;
364}
365#endif /* 0 */
diff --git a/lib/zlib_inflate/infblock.h b/lib/zlib_inflate/infblock.h
deleted file mode 100644
index ceee60b5107c..000000000000
--- a/lib/zlib_inflate/infblock.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/* infblock.h -- header to use infblock.c
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/* WARNING: this file should *not* be used by applications. It is
7 part of the implementation of the compression library and is
8 subject to change. Applications should only use zlib.h.
9 */
10
11#ifndef _INFBLOCK_H
12#define _INFBLOCK_H
13
14struct inflate_blocks_state;
15typedef struct inflate_blocks_state inflate_blocks_statef;
16
17extern inflate_blocks_statef * zlib_inflate_blocks_new (
18 z_streamp z,
19 check_func c, /* check function */
20 uInt w); /* window size */
21
22extern int zlib_inflate_blocks (
23 inflate_blocks_statef *,
24 z_streamp ,
25 int); /* initial return code */
26
27extern void zlib_inflate_blocks_reset (
28 inflate_blocks_statef *,
29 z_streamp ,
30 uLong *); /* check value on output */
31
32extern int zlib_inflate_blocks_free (
33 inflate_blocks_statef *,
34 z_streamp);
35
36#if 0
37extern void zlib_inflate_set_dictionary (
38 inflate_blocks_statef *s,
39 const Byte *d, /* dictionary */
40 uInt n); /* dictionary length */
41#endif /* 0 */
42
43#if 0
44extern int zlib_inflate_blocks_sync_point (
45 inflate_blocks_statef *s);
46#endif /* 0 */
47
48#endif /* _INFBLOCK_H */
diff --git a/lib/zlib_inflate/infcodes.c b/lib/zlib_inflate/infcodes.c
deleted file mode 100644
index 07cd7591cbb7..000000000000
--- a/lib/zlib_inflate/infcodes.c
+++ /dev/null
@@ -1,202 +0,0 @@
1/* infcodes.c -- process literals and length/distance pairs
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include <linux/zutil.h>
7#include "inftrees.h"
8#include "infblock.h"
9#include "infcodes.h"
10#include "infutil.h"
11#include "inffast.h"
12
13/* simplify the use of the inflate_huft type with some defines */
14#define exop word.what.Exop
15#define bits word.what.Bits
16
17inflate_codes_statef *zlib_inflate_codes_new(
18 uInt bl,
19 uInt bd,
20 inflate_huft *tl,
21 inflate_huft *td, /* need separate declaration for Borland C++ */
22 z_streamp z
23)
24{
25 inflate_codes_statef *c;
26
27 c = &WS(z)->working_state;
28 {
29 c->mode = START;
30 c->lbits = (Byte)bl;
31 c->dbits = (Byte)bd;
32 c->ltree = tl;
33 c->dtree = td;
34 }
35 return c;
36}
37
38
39int zlib_inflate_codes(
40 inflate_blocks_statef *s,
41 z_streamp z,
42 int r
43)
44{
45 uInt j; /* temporary storage */
46 inflate_huft *t; /* temporary pointer */
47 uInt e; /* extra bits or operation */
48 uLong b; /* bit buffer */
49 uInt k; /* bits in bit buffer */
50 Byte *p; /* input data pointer */
51 uInt n; /* bytes available there */
52 Byte *q; /* output window write pointer */
53 uInt m; /* bytes to end of window or read pointer */
54 Byte *f; /* pointer to copy strings from */
55 inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
56
57 /* copy input/output information to locals (UPDATE macro restores) */
58 LOAD
59
60 /* process input and output based on current state */
61 while (1) switch (c->mode)
62 { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
63 case START: /* x: set up for LEN */
64#ifndef SLOW
65 if (m >= 258 && n >= 10)
66 {
67 UPDATE
68 r = zlib_inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
69 LOAD
70 if (r != Z_OK)
71 {
72 c->mode = r == Z_STREAM_END ? WASH : BADCODE;
73 break;
74 }
75 }
76#endif /* !SLOW */
77 c->sub.code.need = c->lbits;
78 c->sub.code.tree = c->ltree;
79 c->mode = LEN;
80 case LEN: /* i: get length/literal/eob next */
81 j = c->sub.code.need;
82 NEEDBITS(j)
83 t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]);
84 DUMPBITS(t->bits)
85 e = (uInt)(t->exop);
86 if (e == 0) /* literal */
87 {
88 c->sub.lit = t->base;
89 c->mode = LIT;
90 break;
91 }
92 if (e & 16) /* length */
93 {
94 c->sub.copy.get = e & 15;
95 c->len = t->base;
96 c->mode = LENEXT;
97 break;
98 }
99 if ((e & 64) == 0) /* next table */
100 {
101 c->sub.code.need = e;
102 c->sub.code.tree = t + t->base;
103 break;
104 }
105 if (e & 32) /* end of block */
106 {
107 c->mode = WASH;
108 break;
109 }
110 c->mode = BADCODE; /* invalid code */
111 z->msg = (char*)"invalid literal/length code";
112 r = Z_DATA_ERROR;
113 LEAVE
114 case LENEXT: /* i: getting length extra (have base) */
115 j = c->sub.copy.get;
116 NEEDBITS(j)
117 c->len += (uInt)b & zlib_inflate_mask[j];
118 DUMPBITS(j)
119 c->sub.code.need = c->dbits;
120 c->sub.code.tree = c->dtree;
121 c->mode = DIST;
122 case DIST: /* i: get distance next */
123 j = c->sub.code.need;
124 NEEDBITS(j)
125 t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]);
126 DUMPBITS(t->bits)
127 e = (uInt)(t->exop);
128 if (e & 16) /* distance */
129 {
130 c->sub.copy.get = e & 15;
131 c->sub.copy.dist = t->base;
132 c->mode = DISTEXT;
133 break;
134 }
135 if ((e & 64) == 0) /* next table */
136 {
137 c->sub.code.need = e;
138 c->sub.code.tree = t + t->base;
139 break;
140 }
141 c->mode = BADCODE; /* invalid code */
142 z->msg = (char*)"invalid distance code";
143 r = Z_DATA_ERROR;
144 LEAVE
145 case DISTEXT: /* i: getting distance extra */
146 j = c->sub.copy.get;
147 NEEDBITS(j)
148 c->sub.copy.dist += (uInt)b & zlib_inflate_mask[j];
149 DUMPBITS(j)
150 c->mode = COPY;
151 case COPY: /* o: copying bytes in window, waiting for space */
152 f = q - c->sub.copy.dist;
153 while (f < s->window) /* modulo window size-"while" instead */
154 f += s->end - s->window; /* of "if" handles invalid distances */
155 while (c->len)
156 {
157 NEEDOUT
158 OUTBYTE(*f++)
159 if (f == s->end)
160 f = s->window;
161 c->len--;
162 }
163 c->mode = START;
164 break;
165 case LIT: /* o: got literal, waiting for output space */
166 NEEDOUT
167 OUTBYTE(c->sub.lit)
168 c->mode = START;
169 break;
170 case WASH: /* o: got eob, possibly more output */
171 if (k > 7) /* return unused byte, if any */
172 {
173 k -= 8;
174 n++;
175 p--; /* can always return one */
176 }
177 FLUSH
178 if (s->read != s->write)
179 LEAVE
180 c->mode = END;
181 case END:
182 r = Z_STREAM_END;
183 LEAVE
184 case BADCODE: /* x: got error */
185 r = Z_DATA_ERROR;
186 LEAVE
187 default:
188 r = Z_STREAM_ERROR;
189 LEAVE
190 }
191#ifdef NEED_DUMMY_RETURN
192 return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
193#endif
194}
195
196
197void zlib_inflate_codes_free(
198 inflate_codes_statef *c,
199 z_streamp z
200)
201{
202}
diff --git a/lib/zlib_inflate/infcodes.h b/lib/zlib_inflate/infcodes.h
deleted file mode 100644
index 5cff417523b0..000000000000
--- a/lib/zlib_inflate/infcodes.h
+++ /dev/null
@@ -1,33 +0,0 @@
1/* infcodes.h -- header to use infcodes.c
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/* WARNING: this file should *not* be used by applications. It is
7 part of the implementation of the compression library and is
8 subject to change. Applications should only use zlib.h.
9 */
10
11#ifndef _INFCODES_H
12#define _INFCODES_H
13
14#include "infblock.h"
15
16struct inflate_codes_state;
17typedef struct inflate_codes_state inflate_codes_statef;
18
19extern inflate_codes_statef *zlib_inflate_codes_new (
20 uInt, uInt,
21 inflate_huft *, inflate_huft *,
22 z_streamp );
23
24extern int zlib_inflate_codes (
25 inflate_blocks_statef *,
26 z_streamp ,
27 int);
28
29extern void zlib_inflate_codes_free (
30 inflate_codes_statef *,
31 z_streamp );
32
33#endif /* _INFCODES_H */
diff --git a/lib/zlib_inflate/inffast.c b/lib/zlib_inflate/inffast.c
index 0bd7623fc85a..02a16eacb72d 100644
--- a/lib/zlib_inflate/inffast.c
+++ b/lib/zlib_inflate/inffast.c
@@ -1,176 +1,312 @@
1/* inffast.c -- process literals and length/distance pairs fast 1/* inffast.c -- fast decoding
2 * Copyright (C) 1995-1998 Mark Adler 2 * Copyright (C) 1995-2004 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
6#include <linux/zutil.h> 6#include <linux/zutil.h>
7#include "inftrees.h" 7#include "inftrees.h"
8#include "infblock.h" 8#include "inflate.h"
9#include "infcodes.h"
10#include "infutil.h"
11#include "inffast.h" 9#include "inffast.h"
12 10
13struct inflate_codes_state; 11#ifndef ASMINF
14 12
15/* simplify the use of the inflate_huft type with some defines */ 13/* Allow machine dependent optimization for post-increment or pre-increment.
16#define exop word.what.Exop 14 Based on testing to date,
17#define bits word.what.Bits 15 Pre-increment preferred for:
18 16 - PowerPC G3 (Adler)
19/* macros for bit input with no checking and for returning unused bytes */ 17 - MIPS R5000 (Randers-Pehrson)
20#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} 18 Post-increment preferred for:
21#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;} 19 - none
22 20 No measurable difference:
23/* Called with number of bytes left to write in window at least 258 21 - Pentium III (Anderson)
24 (the maximum string length) and number of input bytes available 22 - M68060 (Nikl)
25 at least ten. The ten bytes are six bytes for the longest length/ 23 */
26 distance pair plus four bytes for overloading the bit buffer. */ 24#ifdef POSTINC
27 25# define OFF 0
28int zlib_inflate_fast( 26# define PUP(a) *(a)++
29 uInt bl, 27#else
30 uInt bd, 28# define OFF 1
31 inflate_huft *tl, 29# define PUP(a) *++(a)
32 inflate_huft *td, /* need separate declaration for Borland C++ */ 30#endif
33 inflate_blocks_statef *s, 31
34 z_streamp z 32/*
35) 33 Decode literal, length, and distance codes and write out the resulting
34 literal and match bytes until either not enough input or output is
35 available, an end-of-block is encountered, or a data error is encountered.
36 When large enough input and output buffers are supplied to inflate(), for
37 example, a 16K input buffer and a 64K output buffer, more than 95% of the
38 inflate execution time is spent in this routine.
39
40 Entry assumptions:
41
42 state->mode == LEN
43 strm->avail_in >= 6
44 strm->avail_out >= 258
45 start >= strm->avail_out
46 state->bits < 8
47
48 On return, state->mode is one of:
49
50 LEN -- ran out of enough output space or enough available input
51 TYPE -- reached end of block code, inflate() to interpret next block
52 BAD -- error in block data
53
54 Notes:
55
56 - The maximum input bits used by a length/distance pair is 15 bits for the
57 length code, 5 bits for the length extra, 15 bits for the distance code,
58 and 13 bits for the distance extra. This totals 48 bits, or six bytes.
59 Therefore if strm->avail_in >= 6, then there is enough input to avoid
60 checking for available input while decoding.
61
62 - The maximum bytes that a single length/distance pair can output is 258
63 bytes, which is the maximum length that can be coded. inflate_fast()
64 requires strm->avail_out >= 258 for each loop to avoid checking for
65 output space.
66 */
67void inflate_fast(strm, start)
68z_streamp strm;
69unsigned start; /* inflate()'s starting value for strm->avail_out */
36{ 70{
37 inflate_huft *t; /* temporary pointer */ 71 struct inflate_state *state;
38 uInt e; /* extra bits or operation */ 72 unsigned char *in; /* local strm->next_in */
39 uLong b; /* bit buffer */ 73 unsigned char *last; /* while in < last, enough input available */
40 uInt k; /* bits in bit buffer */ 74 unsigned char *out; /* local strm->next_out */
41 Byte *p; /* input data pointer */ 75 unsigned char *beg; /* inflate()'s initial strm->next_out */
42 uInt n; /* bytes available there */ 76 unsigned char *end; /* while out < end, enough space available */
43 Byte *q; /* output window write pointer */ 77#ifdef INFLATE_STRICT
44 uInt m; /* bytes to end of window or read pointer */ 78 unsigned dmax; /* maximum distance from zlib header */
45 uInt ml; /* mask for literal/length tree */ 79#endif
46 uInt md; /* mask for distance tree */ 80 unsigned wsize; /* window size or zero if not using window */
47 uInt c; /* bytes to copy */ 81 unsigned whave; /* valid bytes in the window */
48 uInt d; /* distance back to copy from */ 82 unsigned write; /* window write index */
49 Byte *r; /* copy source pointer */ 83 unsigned char *window; /* allocated sliding window, if wsize != 0 */
50 84 unsigned long hold; /* local strm->hold */
51 /* load input, output, bit values */ 85 unsigned bits; /* local strm->bits */
52 LOAD 86 code const *lcode; /* local strm->lencode */
53 87 code const *dcode; /* local strm->distcode */
54 /* initialize masks */ 88 unsigned lmask; /* mask for first level of length codes */
55 ml = zlib_inflate_mask[bl]; 89 unsigned dmask; /* mask for first level of distance codes */
56 md = zlib_inflate_mask[bd]; 90 code this; /* retrieved table entry */
57 91 unsigned op; /* code bits, operation, extra bits, or */
58 /* do until not enough input or output space for fast loop */ 92 /* window position, window bytes to copy */
59 do { /* assume called with m >= 258 && n >= 10 */ 93 unsigned len; /* match length, unused bytes */
60 /* get literal/length code */ 94 unsigned dist; /* match distance */
61 GRABBITS(20) /* max bits for literal/length code */ 95 unsigned char *from; /* where to copy match from */
62 if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) 96
63 { 97 /* copy state to local variables */
64 DUMPBITS(t->bits) 98 state = (struct inflate_state *)strm->state;
65 *q++ = (Byte)t->base; 99 in = strm->next_in - OFF;
66 m--; 100 last = in + (strm->avail_in - 5);
67 continue; 101 out = strm->next_out - OFF;
68 } 102 beg = out - (start - strm->avail_out);
103 end = out + (strm->avail_out - 257);
104#ifdef INFLATE_STRICT
105 dmax = state->dmax;
106#endif
107 wsize = state->wsize;
108 whave = state->whave;
109 write = state->write;
110 window = state->window;
111 hold = state->hold;
112 bits = state->bits;
113 lcode = state->lencode;
114 dcode = state->distcode;
115 lmask = (1U << state->lenbits) - 1;
116 dmask = (1U << state->distbits) - 1;
117
118 /* decode literals and length/distances until end-of-block or not enough
119 input data or output space */
69 do { 120 do {
70 DUMPBITS(t->bits) 121 if (bits < 15) {
71 if (e & 16) 122 hold += (unsigned long)(PUP(in)) << bits;
72 { 123 bits += 8;
73 /* get extra bits for length */ 124 hold += (unsigned long)(PUP(in)) << bits;
74 e &= 15; 125 bits += 8;
75 c = t->base + ((uInt)b & zlib_inflate_mask[e]); 126 }
76 DUMPBITS(e) 127 this = lcode[hold & lmask];
77 128 dolen:
78 /* decode distance base of block to copy */ 129 op = (unsigned)(this.bits);
79 GRABBITS(15); /* max bits for distance code */ 130 hold >>= op;
80 e = (t = td + ((uInt)b & md))->exop; 131 bits -= op;
81 do { 132 op = (unsigned)(this.op);
82 DUMPBITS(t->bits) 133 if (op == 0) { /* literal */
83 if (e & 16) 134 PUP(out) = (unsigned char)(this.val);
84 { 135 }
85 /* get extra bits to add to distance base */ 136 else if (op & 16) { /* length base */
86 e &= 15; 137 len = (unsigned)(this.val);
87 GRABBITS(e) /* get extra bits (up to 13) */ 138 op &= 15; /* number of extra bits */
88 d = t->base + ((uInt)b & zlib_inflate_mask[e]); 139 if (op) {
89 DUMPBITS(e) 140 if (bits < op) {
90 141 hold += (unsigned long)(PUP(in)) << bits;
91 /* do the copy */ 142 bits += 8;
92 m -= c; 143 }
93 r = q - d; 144 len += (unsigned)hold & ((1U << op) - 1);
94 if (r < s->window) /* wrap if needed */ 145 hold >>= op;
95 { 146 bits -= op;
96 do { 147 }
97 r += s->end - s->window; /* force pointer in window */ 148 if (bits < 15) {
98 } while (r < s->window); /* covers invalid distances */ 149 hold += (unsigned long)(PUP(in)) << bits;
99 e = s->end - r; 150 bits += 8;
100 if (c > e) 151 hold += (unsigned long)(PUP(in)) << bits;
101 { 152 bits += 8;
102 c -= e; /* wrapped copy */ 153 }
103 do { 154 this = dcode[hold & dmask];
104 *q++ = *r++; 155 dodist:
105 } while (--e); 156 op = (unsigned)(this.bits);
106 r = s->window; 157 hold >>= op;
107 do { 158 bits -= op;
108 *q++ = *r++; 159 op = (unsigned)(this.op);
109 } while (--c); 160 if (op & 16) { /* distance base */
110 } 161 dist = (unsigned)(this.val);
111 else /* normal copy */ 162 op &= 15; /* number of extra bits */
112 { 163 if (bits < op) {
113 *q++ = *r++; c--; 164 hold += (unsigned long)(PUP(in)) << bits;
114 *q++ = *r++; c--; 165 bits += 8;
115 do { 166 if (bits < op) {
116 *q++ = *r++; 167 hold += (unsigned long)(PUP(in)) << bits;
117 } while (--c); 168 bits += 8;
118 } 169 }
170 }
171 dist += (unsigned)hold & ((1U << op) - 1);
172#ifdef INFLATE_STRICT
173 if (dist > dmax) {
174 strm->msg = (char *)"invalid distance too far back";
175 state->mode = BAD;
176 break;
177 }
178#endif
179 hold >>= op;
180 bits -= op;
181 op = (unsigned)(out - beg); /* max distance in output */
182 if (dist > op) { /* see if copy from window */
183 op = dist - op; /* distance back in window */
184 if (op > whave) {
185 strm->msg = (char *)"invalid distance too far back";
186 state->mode = BAD;
187 break;
188 }
189 from = window - OFF;
190 if (write == 0) { /* very common case */
191 from += wsize - op;
192 if (op < len) { /* some from window */
193 len -= op;
194 do {
195 PUP(out) = PUP(from);
196 } while (--op);
197 from = out - dist; /* rest from output */
198 }
199 }
200 else if (write < op) { /* wrap around window */
201 from += wsize + write - op;
202 op -= write;
203 if (op < len) { /* some from end of window */
204 len -= op;
205 do {
206 PUP(out) = PUP(from);
207 } while (--op);
208 from = window - OFF;
209 if (write < len) { /* some from start of window */
210 op = write;
211 len -= op;
212 do {
213 PUP(out) = PUP(from);
214 } while (--op);
215 from = out - dist; /* rest from output */
216 }
217 }
218 }
219 else { /* contiguous in window */
220 from += write - op;
221 if (op < len) { /* some from window */
222 len -= op;
223 do {
224 PUP(out) = PUP(from);
225 } while (--op);
226 from = out - dist; /* rest from output */
227 }
228 }
229 while (len > 2) {
230 PUP(out) = PUP(from);
231 PUP(out) = PUP(from);
232 PUP(out) = PUP(from);
233 len -= 3;
234 }
235 if (len) {
236 PUP(out) = PUP(from);
237 if (len > 1)
238 PUP(out) = PUP(from);
239 }
240 }
241 else {
242 from = out - dist; /* copy direct from output */
243 do { /* minimum length is three */
244 PUP(out) = PUP(from);
245 PUP(out) = PUP(from);
246 PUP(out) = PUP(from);
247 len -= 3;
248 } while (len > 2);
249 if (len) {
250 PUP(out) = PUP(from);
251 if (len > 1)
252 PUP(out) = PUP(from);
253 }
254 }
255 }
256 else if ((op & 64) == 0) { /* 2nd level distance code */
257 this = dcode[this.val + (hold & ((1U << op) - 1))];
258 goto dodist;
119 } 259 }
120 else /* normal copy */ 260 else {
121 { 261 strm->msg = (char *)"invalid distance code";
122 *q++ = *r++; c--; 262 state->mode = BAD;
123 *q++ = *r++; c--; 263 break;
124 do {
125 *q++ = *r++;
126 } while (--c);
127 } 264 }
265 }
266 else if ((op & 64) == 0) { /* 2nd level length code */
267 this = lcode[this.val + (hold & ((1U << op) - 1))];
268 goto dolen;
269 }
270 else if (op & 32) { /* end-of-block */
271 state->mode = TYPE;
128 break; 272 break;
129 }
130 else if ((e & 64) == 0)
131 {
132 t += t->base;
133 e = (t += ((uInt)b & zlib_inflate_mask[e]))->exop;
134 }
135 else
136 {
137 z->msg = (char*)"invalid distance code";
138 UNGRAB
139 UPDATE
140 return Z_DATA_ERROR;
141 }
142 } while (1);
143 break;
144 }
145 if ((e & 64) == 0)
146 {
147 t += t->base;
148 if ((e = (t += ((uInt)b & zlib_inflate_mask[e]))->exop) == 0)
149 {
150 DUMPBITS(t->bits)
151 *q++ = (Byte)t->base;
152 m--;
153 break;
154 } 273 }
155 } 274 else {
156 else if (e & 32) 275 strm->msg = (char *)"invalid literal/length code";
157 { 276 state->mode = BAD;
158 UNGRAB 277 break;
159 UPDATE 278 }
160 return Z_STREAM_END; 279 } while (in < last && out < end);
161 } 280
162 else 281 /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
163 { 282 len = bits >> 3;
164 z->msg = (char*)"invalid literal/length code"; 283 in -= len;
165 UNGRAB 284 bits -= len << 3;
166 UPDATE 285 hold &= (1U << bits) - 1;
167 return Z_DATA_ERROR; 286
168 } 287 /* update state and return */
169 } while (1); 288 strm->next_in = in + OFF;
170 } while (m >= 258 && n >= 10); 289 strm->next_out = out + OFF;
171 290 strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
172 /* not enough input or output--restore pointers and return */ 291 strm->avail_out = (unsigned)(out < end ?
173 UNGRAB 292 257 + (end - out) : 257 - (out - end));
174 UPDATE 293 state->hold = hold;
175 return Z_OK; 294 state->bits = bits;
295 return;
176} 296}
297
298/*
299 inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
300 - Using bit fields for code structure
301 - Different op definition to avoid & for extra bits (do & for table bits)
302 - Three separate decoding do-loops for direct, window, and write == 0
303 - Special case for distance > 1 copies to do overlapped load and store copy
304 - Explicit branch predictions (based on measured branch probabilities)
305 - Deferring match copy and interspersed it with decoding subsequent codes
306 - Swapping literal/length else
307 - Swapping window/direct else
308 - Larger unrolled copy loops (three is about right)
309 - Moving len -= 3 statement into middle of loop
310 */
311
312#endif /* !ASMINF */
diff --git a/lib/zlib_inflate/inffast.h b/lib/zlib_inflate/inffast.h
index fc720f0fa7f5..40315d9fddc4 100644
--- a/lib/zlib_inflate/inffast.h
+++ b/lib/zlib_inflate/inffast.h
@@ -1,6 +1,6 @@
1/* inffast.h -- header to use inffast.c 1/* inffast.h -- header to use inffast.c
2 * Copyright (C) 1995-1998 Mark Adler 2 * Copyright (C) 1995-2003 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
6/* WARNING: this file should *not* be used by applications. It is 6/* WARNING: this file should *not* be used by applications. It is
@@ -8,10 +8,4 @@
8 subject to change. Applications should only use zlib.h. 8 subject to change. Applications should only use zlib.h.
9 */ 9 */
10 10
11extern int zlib_inflate_fast ( 11void inflate_fast (z_streamp strm, unsigned start);
12 uInt,
13 uInt,
14 inflate_huft *,
15 inflate_huft *,
16 inflate_blocks_statef *,
17 z_streamp );
diff --git a/lib/zlib_inflate/inffixed.h b/lib/zlib_inflate/inffixed.h
new file mode 100644
index 000000000000..75ed4b5978de
--- /dev/null
+++ b/lib/zlib_inflate/inffixed.h
@@ -0,0 +1,94 @@
1 /* inffixed.h -- table for decoding fixed codes
2 * Generated automatically by makefixed().
3 */
4
5 /* WARNING: this file should *not* be used by applications. It
6 is part of the implementation of the compression library and
7 is subject to change. Applications should only use zlib.h.
8 */
9
10 static const code lenfix[512] = {
11 {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
12 {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
13 {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
14 {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
15 {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
16 {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
17 {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
18 {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
19 {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
20 {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
21 {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
22 {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
23 {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
24 {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
25 {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
26 {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
27 {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
28 {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
29 {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
30 {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
31 {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
32 {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
33 {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
34 {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
35 {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
36 {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
37 {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
38 {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
39 {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
40 {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
41 {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
42 {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
43 {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
44 {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
45 {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
46 {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
47 {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
48 {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
49 {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
50 {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
51 {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
52 {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
53 {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
54 {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
55 {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
56 {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
57 {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
58 {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
59 {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
60 {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
61 {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
62 {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
63 {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
64 {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
65 {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
66 {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
67 {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
68 {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
69 {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
70 {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
71 {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
72 {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
73 {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
74 {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
75 {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
76 {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
77 {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
78 {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
79 {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
80 {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
81 {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
82 {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
83 {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
84 {0,9,255}
85 };
86
87 static const code distfix[32] = {
88 {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
89 {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
90 {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
91 {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
92 {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
93 {22,5,193},{64,5,0}
94 };
diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c
index 31b9e9054bf7..7f922dccf1a5 100644
--- a/lib/zlib_inflate/inflate.c
+++ b/lib/zlib_inflate/inflate.c
@@ -1,89 +1,148 @@
1/* inflate.c -- zlib interface to inflate modules 1/* inflate.c -- zlib decompression
2 * Copyright (C) 1995-1998 Mark Adler 2 * Copyright (C) 1995-2005 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 *
5 * Based on zlib 1.2.3 but modified for the Linux Kernel by
6 * Richard Purdie <richard@openedhand.com>
7 *
8 * Changes mainly for static instead of dynamic memory allocation
9 *
4 */ 10 */
5 11
6#include <linux/zutil.h> 12#include <linux/zutil.h>
7#include "infblock.h" 13#include "inftrees.h"
14#include "inflate.h"
15#include "inffast.h"
8#include "infutil.h" 16#include "infutil.h"
9 17
10int zlib_inflate_workspacesize(void) 18int zlib_inflate_workspacesize(void)
11{ 19{
12 return sizeof(struct inflate_workspace); 20 return sizeof(struct inflate_workspace);
13} 21}
14 22
23int zlib_inflateReset(z_streamp strm)
24{
25 struct inflate_state *state;
26
27 if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
28 state = (struct inflate_state *)strm->state;
29 strm->total_in = strm->total_out = state->total = 0;
30 strm->msg = NULL;
31 strm->adler = 1; /* to support ill-conceived Java test suite */
32 state->mode = HEAD;
33 state->last = 0;
34 state->havedict = 0;
35 state->dmax = 32768U;
36 state->hold = 0;
37 state->bits = 0;
38 state->lencode = state->distcode = state->next = state->codes;
15 39
16int zlib_inflateReset( 40 /* Initialise Window */
17 z_streamp z 41 state->wsize = 1U << state->wbits;
18) 42 state->write = 0;
43 state->whave = 0;
44
45 return Z_OK;
46}
47
48#if 0
49int zlib_inflatePrime(z_streamp strm, int bits, int value)
19{ 50{
20 if (z == NULL || z->state == NULL || z->workspace == NULL) 51 struct inflate_state *state;
21 return Z_STREAM_ERROR; 52
22 z->total_in = z->total_out = 0; 53 if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
23 z->msg = NULL; 54 state = (struct inflate_state *)strm->state;
24 z->state->mode = z->state->nowrap ? BLOCKS : METHOD; 55 if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
25 zlib_inflate_blocks_reset(z->state->blocks, z, NULL); 56 value &= (1L << bits) - 1;
26 return Z_OK; 57 state->hold += value << state->bits;
58 state->bits += bits;
59 return Z_OK;
27} 60}
61#endif
62
63int zlib_inflateInit2(z_streamp strm, int windowBits)
64{
65 struct inflate_state *state;
66
67 if (strm == NULL) return Z_STREAM_ERROR;
68 strm->msg = NULL; /* in case we return an error */
69
70 state = &WS(strm)->inflate_state;
71 strm->state = (struct internal_state *)state;
72
73 if (windowBits < 0) {
74 state->wrap = 0;
75 windowBits = -windowBits;
76 }
77 else {
78 state->wrap = (windowBits >> 4) + 1;
79 }
80 if (windowBits < 8 || windowBits > 15) {
81 return Z_STREAM_ERROR;
82 }
83 state->wbits = (unsigned)windowBits;
84 state->window = &WS(strm)->working_window[0];
28 85
86 return zlib_inflateReset(strm);
87}
29 88
30int zlib_inflateEnd( 89/*
31 z_streamp z 90 Return state with length and distance decoding tables and index sizes set to
32) 91 fixed code decoding. This returns fixed tables from inffixed.h.
92 */
93static void zlib_fixedtables(struct inflate_state *state)
33{ 94{
34 if (z == NULL || z->state == NULL || z->workspace == NULL) 95# include "inffixed.h"
35 return Z_STREAM_ERROR; 96 state->lencode = lenfix;
36 if (z->state->blocks != NULL) 97 state->lenbits = 9;
37 zlib_inflate_blocks_free(z->state->blocks, z); 98 state->distcode = distfix;
38 z->state = NULL; 99 state->distbits = 5;
39 return Z_OK;
40} 100}
41 101
42 102
43int zlib_inflateInit2_( 103/*
44 z_streamp z, 104 Update the window with the last wsize (normally 32K) bytes written before
45 int w, 105 returning. This is only called when a window is already in use, or when
46 const char *version, 106 output has been written during this inflate call, but the end of the deflate
47 int stream_size 107 stream has not been reached yet. It is also called to window dictionary data
48) 108 when a dictionary is loaded.
109
110 Providing output buffers larger than 32K to inflate() should provide a speed
111 advantage, since only the last 32K of output is copied to the sliding window
112 upon return from inflate(), and since all distances after the first 32K of
113 output will fall in the output data, making match copies simpler and faster.
114 The advantage may be dependent on the size of the processor's data caches.
115 */
116static void zlib_updatewindow(z_streamp strm, unsigned out)
49{ 117{
50 if (version == NULL || version[0] != ZLIB_VERSION[0] || 118 struct inflate_state *state;
51 stream_size != sizeof(z_stream) || z->workspace == NULL) 119 unsigned copy, dist;
52 return Z_VERSION_ERROR; 120
53 121 state = (struct inflate_state *)strm->state;
54 /* initialize state */ 122
55 z->msg = NULL; 123 /* copy state->wsize or less output bytes into the circular window */
56 z->state = &WS(z)->internal_state; 124 copy = out - strm->avail_out;
57 z->state->blocks = NULL; 125 if (copy >= state->wsize) {
58 126 memcpy(state->window, strm->next_out - state->wsize, state->wsize);
59 /* handle undocumented nowrap option (no zlib header or check) */ 127 state->write = 0;
60 z->state->nowrap = 0; 128 state->whave = state->wsize;
61 if (w < 0) 129 }
62 { 130 else {
63 w = - w; 131 dist = state->wsize - state->write;
64 z->state->nowrap = 1; 132 if (dist > copy) dist = copy;
65 } 133 memcpy(state->window + state->write, strm->next_out - copy, dist);
66 134 copy -= dist;
67 /* set window size */ 135 if (copy) {
68 if (w < 8 || w > 15) 136 memcpy(state->window, strm->next_out - copy, copy);
69 { 137 state->write = copy;
70 zlib_inflateEnd(z); 138 state->whave = state->wsize;
71 return Z_STREAM_ERROR; 139 }
72 } 140 else {
73 z->state->wbits = (uInt)w; 141 state->write += dist;
74 142 if (state->write == state->wsize) state->write = 0;
75 /* create inflate_blocks state */ 143 if (state->whave < state->wsize) state->whave += dist;
76 if ((z->state->blocks = 144 }
77 zlib_inflate_blocks_new(z, z->state->nowrap ? NULL : zlib_adler32, (uInt)1 << w)) 145 }
78 == NULL)
79 {
80 zlib_inflateEnd(z);
81 return Z_MEM_ERROR;
82 }
83
84 /* reset state */
85 zlib_inflateReset(z);
86 return Z_OK;
87} 146}
88 147
89 148
@@ -91,157 +150,764 @@ int zlib_inflateInit2_(
91 * At the end of a Deflate-compressed PPP packet, we expect to have seen 150 * At the end of a Deflate-compressed PPP packet, we expect to have seen
92 * a `stored' block type value but not the (zero) length bytes. 151 * a `stored' block type value but not the (zero) length bytes.
93 */ 152 */
94static int zlib_inflate_packet_flush(inflate_blocks_statef *s) 153/*
154 Returns true if inflate is currently at the end of a block generated by
155 Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
156 implementation to provide an additional safety check. PPP uses
157 Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
158 block. When decompressing, PPP checks that at the end of input packet,
159 inflate is waiting for these length bytes.
160 */
161static int zlib_inflateSyncPacket(z_streamp strm)
95{ 162{
96 if (s->mode != LENS) 163 struct inflate_state *state;
97 return Z_DATA_ERROR; 164
98 s->mode = TYPE; 165 if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
166 state = (struct inflate_state *)strm->state;
167
168 if (state->mode == STORED && state->bits == 0) {
169 state->mode = TYPE;
170 return Z_OK;
171 }
172 return Z_DATA_ERROR;
173}
174
175/* Macros for inflate(): */
176
177/* check function to use adler32() for zlib or crc32() for gzip */
178#define UPDATE(check, buf, len) zlib_adler32(check, buf, len)
179
180/* Load registers with state in inflate() for speed */
181#define LOAD() \
182 do { \
183 put = strm->next_out; \
184 left = strm->avail_out; \
185 next = strm->next_in; \
186 have = strm->avail_in; \
187 hold = state->hold; \
188 bits = state->bits; \
189 } while (0)
190
191/* Restore state from registers in inflate() */
192#define RESTORE() \
193 do { \
194 strm->next_out = put; \
195 strm->avail_out = left; \
196 strm->next_in = next; \
197 strm->avail_in = have; \
198 state->hold = hold; \
199 state->bits = bits; \
200 } while (0)
201
202/* Clear the input bit accumulator */
203#define INITBITS() \
204 do { \
205 hold = 0; \
206 bits = 0; \
207 } while (0)
208
209/* Get a byte of input into the bit accumulator, or return from inflate()
210 if there is no input available. */
211#define PULLBYTE() \
212 do { \
213 if (have == 0) goto inf_leave; \
214 have--; \
215 hold += (unsigned long)(*next++) << bits; \
216 bits += 8; \
217 } while (0)
218
219/* Assure that there are at least n bits in the bit accumulator. If there is
220 not enough available input to do that, then return from inflate(). */
221#define NEEDBITS(n) \
222 do { \
223 while (bits < (unsigned)(n)) \
224 PULLBYTE(); \
225 } while (0)
226
227/* Return the low n bits of the bit accumulator (n < 16) */
228#define BITS(n) \
229 ((unsigned)hold & ((1U << (n)) - 1))
230
231/* Remove n bits from the bit accumulator */
232#define DROPBITS(n) \
233 do { \
234 hold >>= (n); \
235 bits -= (unsigned)(n); \
236 } while (0)
237
238/* Remove zero to seven bits as needed to go to a byte boundary */
239#define BYTEBITS() \
240 do { \
241 hold >>= bits & 7; \
242 bits -= bits & 7; \
243 } while (0)
244
245/* Reverse the bytes in a 32-bit value */
246#define REVERSE(q) \
247 ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
248 (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
249
250/*
251 inflate() uses a state machine to process as much input data and generate as
252 much output data as possible before returning. The state machine is
253 structured roughly as follows:
254
255 for (;;) switch (state) {
256 ...
257 case STATEn:
258 if (not enough input data or output space to make progress)
259 return;
260 ... make progress ...
261 state = STATEm;
262 break;
263 ...
264 }
265
266 so when inflate() is called again, the same case is attempted again, and
267 if the appropriate resources are provided, the machine proceeds to the
268 next state. The NEEDBITS() macro is usually the way the state evaluates
269 whether it can proceed or should return. NEEDBITS() does the return if
270 the requested bits are not available. The typical use of the BITS macros
271 is:
272
273 NEEDBITS(n);
274 ... do something with BITS(n) ...
275 DROPBITS(n);
276
277 where NEEDBITS(n) either returns from inflate() if there isn't enough
278 input left to load n bits into the accumulator, or it continues. BITS(n)
279 gives the low n bits in the accumulator. When done, DROPBITS(n) drops
280 the low n bits off the accumulator. INITBITS() clears the accumulator
281 and sets the number of available bits to zero. BYTEBITS() discards just
282 enough bits to put the accumulator on a byte boundary. After BYTEBITS()
283 and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
284
285 NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
286 if there is no input available. The decoding of variable length codes uses
287 PULLBYTE() directly in order to pull just enough bytes to decode the next
288 code, and no more.
289
290 Some states loop until they get enough input, making sure that enough
291 state information is maintained to continue the loop where it left off
292 if NEEDBITS() returns in the loop. For example, want, need, and keep
293 would all have to actually be part of the saved state in case NEEDBITS()
294 returns:
295
296 case STATEw:
297 while (want < need) {
298 NEEDBITS(n);
299 keep[want++] = BITS(n);
300 DROPBITS(n);
301 }
302 state = STATEx;
303 case STATEx:
304
305 As shown above, if the next state is also the next case, then the break
306 is omitted.
307
308 A state may also return if there is not enough output space available to
309 complete that state. Those states are copying stored data, writing a
310 literal byte, and copying a matching string.
311
312 When returning, a "goto inf_leave" is used to update the total counters,
313 update the check value, and determine whether any progress has been made
314 during that inflate() call in order to return the proper return code.
315 Progress is defined as a change in either strm->avail_in or strm->avail_out.
316 When there is a window, goto inf_leave will update the window with the last
317 output written. If a goto inf_leave occurs in the middle of decompression
318 and there is no window currently, goto inf_leave will create one and copy
319 output to the window for the next call of inflate().
320
321 In this implementation, the flush parameter of inflate() only affects the
322 return code (per zlib.h). inflate() always writes as much as possible to
323 strm->next_out, given the space available and the provided input--the effect
324 documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
325 the allocation of and copying into a sliding window until necessary, which
326 provides the effect documented in zlib.h for Z_FINISH when the entire input
327 stream available. So the only thing the flush parameter actually does is:
328 when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
329 will return Z_BUF_ERROR if it has not reached the end of the stream.
330 */
331
332int zlib_inflate(z_streamp strm, int flush)
333{
334 struct inflate_state *state;
335 unsigned char *next; /* next input */
336 unsigned char *put; /* next output */
337 unsigned have, left; /* available input and output */
338 unsigned long hold; /* bit buffer */
339 unsigned bits; /* bits in bit buffer */
340 unsigned in, out; /* save starting available input and output */
341 unsigned copy; /* number of stored or match bytes to copy */
342 unsigned char *from; /* where to copy match bytes from */
343 code this; /* current decoding table entry */
344 code last; /* parent table entry */
345 unsigned len; /* length to copy for repeats, bits to drop */
346 int ret; /* return code */
347 static const unsigned short order[19] = /* permutation of code lengths */
348 {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
349
350 if (strm == NULL || strm->state == NULL || strm->next_out == NULL ||
351 (strm->next_in == NULL && strm->avail_in != 0))
352 return Z_STREAM_ERROR;
353
354 state = (struct inflate_state *)strm->state;
355
356 if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
357 LOAD();
358 in = have;
359 out = left;
360 ret = Z_OK;
361 for (;;)
362 switch (state->mode) {
363 case HEAD:
364 if (state->wrap == 0) {
365 state->mode = TYPEDO;
366 break;
367 }
368 NEEDBITS(16);
369 if (
370 ((BITS(8) << 8) + (hold >> 8)) % 31) {
371 strm->msg = (char *)"incorrect header check";
372 state->mode = BAD;
373 break;
374 }
375 if (BITS(4) != Z_DEFLATED) {
376 strm->msg = (char *)"unknown compression method";
377 state->mode = BAD;
378 break;
379 }
380 DROPBITS(4);
381 len = BITS(4) + 8;
382 if (len > state->wbits) {
383 strm->msg = (char *)"invalid window size";
384 state->mode = BAD;
385 break;
386 }
387 state->dmax = 1U << len;
388 strm->adler = state->check = zlib_adler32(0L, NULL, 0);
389 state->mode = hold & 0x200 ? DICTID : TYPE;
390 INITBITS();
391 break;
392 case DICTID:
393 NEEDBITS(32);
394 strm->adler = state->check = REVERSE(hold);
395 INITBITS();
396 state->mode = DICT;
397 case DICT:
398 if (state->havedict == 0) {
399 RESTORE();
400 return Z_NEED_DICT;
401 }
402 strm->adler = state->check = zlib_adler32(0L, NULL, 0);
403 state->mode = TYPE;
404 case TYPE:
405 if (flush == Z_BLOCK) goto inf_leave;
406 case TYPEDO:
407 if (state->last) {
408 BYTEBITS();
409 state->mode = CHECK;
410 break;
411 }
412 NEEDBITS(3);
413 state->last = BITS(1);
414 DROPBITS(1);
415 switch (BITS(2)) {
416 case 0: /* stored block */
417 state->mode = STORED;
418 break;
419 case 1: /* fixed block */
420 zlib_fixedtables(state);
421 state->mode = LEN; /* decode codes */
422 break;
423 case 2: /* dynamic block */
424 state->mode = TABLE;
425 break;
426 case 3:
427 strm->msg = (char *)"invalid block type";
428 state->mode = BAD;
429 }
430 DROPBITS(2);
431 break;
432 case STORED:
433 BYTEBITS(); /* go to byte boundary */
434 NEEDBITS(32);
435 if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
436 strm->msg = (char *)"invalid stored block lengths";
437 state->mode = BAD;
438 break;
439 }
440 state->length = (unsigned)hold & 0xffff;
441 INITBITS();
442 state->mode = COPY;
443 case COPY:
444 copy = state->length;
445 if (copy) {
446 if (copy > have) copy = have;
447 if (copy > left) copy = left;
448 if (copy == 0) goto inf_leave;
449 memcpy(put, next, copy);
450 have -= copy;
451 next += copy;
452 left -= copy;
453 put += copy;
454 state->length -= copy;
455 break;
456 }
457 state->mode = TYPE;
458 break;
459 case TABLE:
460 NEEDBITS(14);
461 state->nlen = BITS(5) + 257;
462 DROPBITS(5);
463 state->ndist = BITS(5) + 1;
464 DROPBITS(5);
465 state->ncode = BITS(4) + 4;
466 DROPBITS(4);
467#ifndef PKZIP_BUG_WORKAROUND
468 if (state->nlen > 286 || state->ndist > 30) {
469 strm->msg = (char *)"too many length or distance symbols";
470 state->mode = BAD;
471 break;
472 }
473#endif
474 state->have = 0;
475 state->mode = LENLENS;
476 case LENLENS:
477 while (state->have < state->ncode) {
478 NEEDBITS(3);
479 state->lens[order[state->have++]] = (unsigned short)BITS(3);
480 DROPBITS(3);
481 }
482 while (state->have < 19)
483 state->lens[order[state->have++]] = 0;
484 state->next = state->codes;
485 state->lencode = (code const *)(state->next);
486 state->lenbits = 7;
487 ret = zlib_inflate_table(CODES, state->lens, 19, &(state->next),
488 &(state->lenbits), state->work);
489 if (ret) {
490 strm->msg = (char *)"invalid code lengths set";
491 state->mode = BAD;
492 break;
493 }
494 state->have = 0;
495 state->mode = CODELENS;
496 case CODELENS:
497 while (state->have < state->nlen + state->ndist) {
498 for (;;) {
499 this = state->lencode[BITS(state->lenbits)];
500 if ((unsigned)(this.bits) <= bits) break;
501 PULLBYTE();
502 }
503 if (this.val < 16) {
504 NEEDBITS(this.bits);
505 DROPBITS(this.bits);
506 state->lens[state->have++] = this.val;
507 }
508 else {
509 if (this.val == 16) {
510 NEEDBITS(this.bits + 2);
511 DROPBITS(this.bits);
512 if (state->have == 0) {
513 strm->msg = (char *)"invalid bit length repeat";
514 state->mode = BAD;
515 break;
516 }
517 len = state->lens[state->have - 1];
518 copy = 3 + BITS(2);
519 DROPBITS(2);
520 }
521 else if (this.val == 17) {
522 NEEDBITS(this.bits + 3);
523 DROPBITS(this.bits);
524 len = 0;
525 copy = 3 + BITS(3);
526 DROPBITS(3);
527 }
528 else {
529 NEEDBITS(this.bits + 7);
530 DROPBITS(this.bits);
531 len = 0;
532 copy = 11 + BITS(7);
533 DROPBITS(7);
534 }
535 if (state->have + copy > state->nlen + state->ndist) {
536 strm->msg = (char *)"invalid bit length repeat";
537 state->mode = BAD;
538 break;
539 }
540 while (copy--)
541 state->lens[state->have++] = (unsigned short)len;
542 }
543 }
544
545 /* handle error breaks in while */
546 if (state->mode == BAD) break;
547
548 /* build code tables */
549 state->next = state->codes;
550 state->lencode = (code const *)(state->next);
551 state->lenbits = 9;
552 ret = zlib_inflate_table(LENS, state->lens, state->nlen, &(state->next),
553 &(state->lenbits), state->work);
554 if (ret) {
555 strm->msg = (char *)"invalid literal/lengths set";
556 state->mode = BAD;
557 break;
558 }
559 state->distcode = (code const *)(state->next);
560 state->distbits = 6;
561 ret = zlib_inflate_table(DISTS, state->lens + state->nlen, state->ndist,
562 &(state->next), &(state->distbits), state->work);
563 if (ret) {
564 strm->msg = (char *)"invalid distances set";
565 state->mode = BAD;
566 break;
567 }
568 state->mode = LEN;
569 case LEN:
570 if (have >= 6 && left >= 258) {
571 RESTORE();
572 inflate_fast(strm, out);
573 LOAD();
574 break;
575 }
576 for (;;) {
577 this = state->lencode[BITS(state->lenbits)];
578 if ((unsigned)(this.bits) <= bits) break;
579 PULLBYTE();
580 }
581 if (this.op && (this.op & 0xf0) == 0) {
582 last = this;
583 for (;;) {
584 this = state->lencode[last.val +
585 (BITS(last.bits + last.op) >> last.bits)];
586 if ((unsigned)(last.bits + this.bits) <= bits) break;
587 PULLBYTE();
588 }
589 DROPBITS(last.bits);
590 }
591 DROPBITS(this.bits);
592 state->length = (unsigned)this.val;
593 if ((int)(this.op) == 0) {
594 state->mode = LIT;
595 break;
596 }
597 if (this.op & 32) {
598 state->mode = TYPE;
599 break;
600 }
601 if (this.op & 64) {
602 strm->msg = (char *)"invalid literal/length code";
603 state->mode = BAD;
604 break;
605 }
606 state->extra = (unsigned)(this.op) & 15;
607 state->mode = LENEXT;
608 case LENEXT:
609 if (state->extra) {
610 NEEDBITS(state->extra);
611 state->length += BITS(state->extra);
612 DROPBITS(state->extra);
613 }
614 state->mode = DIST;
615 case DIST:
616 for (;;) {
617 this = state->distcode[BITS(state->distbits)];
618 if ((unsigned)(this.bits) <= bits) break;
619 PULLBYTE();
620 }
621 if ((this.op & 0xf0) == 0) {
622 last = this;
623 for (;;) {
624 this = state->distcode[last.val +
625 (BITS(last.bits + last.op) >> last.bits)];
626 if ((unsigned)(last.bits + this.bits) <= bits) break;
627 PULLBYTE();
628 }
629 DROPBITS(last.bits);
630 }
631 DROPBITS(this.bits);
632 if (this.op & 64) {
633 strm->msg = (char *)"invalid distance code";
634 state->mode = BAD;
635 break;
636 }
637 state->offset = (unsigned)this.val;
638 state->extra = (unsigned)(this.op) & 15;
639 state->mode = DISTEXT;
640 case DISTEXT:
641 if (state->extra) {
642 NEEDBITS(state->extra);
643 state->offset += BITS(state->extra);
644 DROPBITS(state->extra);
645 }
646#ifdef INFLATE_STRICT
647 if (state->offset > state->dmax) {
648 strm->msg = (char *)"invalid distance too far back";
649 state->mode = BAD;
650 break;
651 }
652#endif
653 if (state->offset > state->whave + out - left) {
654 strm->msg = (char *)"invalid distance too far back";
655 state->mode = BAD;
656 break;
657 }
658 state->mode = MATCH;
659 case MATCH:
660 if (left == 0) goto inf_leave;
661 copy = out - left;
662 if (state->offset > copy) { /* copy from window */
663 copy = state->offset - copy;
664 if (copy > state->write) {
665 copy -= state->write;
666 from = state->window + (state->wsize - copy);
667 }
668 else
669 from = state->window + (state->write - copy);
670 if (copy > state->length) copy = state->length;
671 }
672 else { /* copy from output */
673 from = put - state->offset;
674 copy = state->length;
675 }
676 if (copy > left) copy = left;
677 left -= copy;
678 state->length -= copy;
679 do {
680 *put++ = *from++;
681 } while (--copy);
682 if (state->length == 0) state->mode = LEN;
683 break;
684 case LIT:
685 if (left == 0) goto inf_leave;
686 *put++ = (unsigned char)(state->length);
687 left--;
688 state->mode = LEN;
689 break;
690 case CHECK:
691 if (state->wrap) {
692 NEEDBITS(32);
693 out -= left;
694 strm->total_out += out;
695 state->total += out;
696 if (out)
697 strm->adler = state->check =
698 UPDATE(state->check, put - out, out);
699 out = left;
700 if ((
701 REVERSE(hold)) != state->check) {
702 strm->msg = (char *)"incorrect data check";
703 state->mode = BAD;
704 break;
705 }
706 INITBITS();
707 }
708 state->mode = DONE;
709 case DONE:
710 ret = Z_STREAM_END;
711 goto inf_leave;
712 case BAD:
713 ret = Z_DATA_ERROR;
714 goto inf_leave;
715 case MEM:
716 return Z_MEM_ERROR;
717 case SYNC:
718 default:
719 return Z_STREAM_ERROR;
720 }
721
722 /*
723 Return from inflate(), updating the total counts and the check value.
724 If there was no progress during the inflate() call, return a buffer
725 error. Call zlib_updatewindow() to create and/or update the window state.
726 */
727 inf_leave:
728 RESTORE();
729 if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
730 zlib_updatewindow(strm, out);
731
732 in -= strm->avail_in;
733 out -= strm->avail_out;
734 strm->total_in += in;
735 strm->total_out += out;
736 state->total += out;
737 if (state->wrap && out)
738 strm->adler = state->check =
739 UPDATE(state->check, strm->next_out - out, out);
740
741 strm->data_type = state->bits + (state->last ? 64 : 0) +
742 (state->mode == TYPE ? 128 : 0);
743 if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
744 ret = Z_BUF_ERROR;
745
746 if (flush == Z_PACKET_FLUSH && ret == Z_OK &&
747 (strm->avail_out != 0 || strm->avail_in == 0))
748 return zlib_inflateSyncPacket(strm);
749 return ret;
750}
751
752int zlib_inflateEnd(z_streamp strm)
753{
754 if (strm == NULL || strm->state == NULL)
755 return Z_STREAM_ERROR;
99 return Z_OK; 756 return Z_OK;
100} 757}
101 758
759#if 0
760int zlib_inflateSetDictionary(z_streamp strm, const Byte *dictionary,
761 uInt dictLength)
762{
763 struct inflate_state *state;
764 unsigned long id;
765
766 /* check state */
767 if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
768 state = (struct inflate_state *)strm->state;
769 if (state->wrap != 0 && state->mode != DICT)
770 return Z_STREAM_ERROR;
771
772 /* check for correct dictionary id */
773 if (state->mode == DICT) {
774 id = zlib_adler32(0L, NULL, 0);
775 id = zlib_adler32(id, dictionary, dictLength);
776 if (id != state->check)
777 return Z_DATA_ERROR;
778 }
779
780 /* copy dictionary to window */
781 zlib_updatewindow(strm, strm->avail_out);
102 782
103int zlib_inflateInit_( 783 if (dictLength > state->wsize) {
104 z_streamp z, 784 memcpy(state->window, dictionary + dictLength - state->wsize,
105 const char *version, 785 state->wsize);
106 int stream_size 786 state->whave = state->wsize;
107) 787 }
788 else {
789 memcpy(state->window + state->wsize - dictLength, dictionary,
790 dictLength);
791 state->whave = dictLength;
792 }
793 state->havedict = 1;
794 return Z_OK;
795}
796#endif
797
798#if 0
799/*
800 Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
801 or when out of input. When called, *have is the number of pattern bytes
802 found in order so far, in 0..3. On return *have is updated to the new
803 state. If on return *have equals four, then the pattern was found and the
804 return value is how many bytes were read including the last byte of the
805 pattern. If *have is less than four, then the pattern has not been found
806 yet and the return value is len. In the latter case, zlib_syncsearch() can be
807 called again with more data and the *have state. *have is initialized to
808 zero for the first call.
809 */
810static unsigned zlib_syncsearch(unsigned *have, unsigned char *buf,
811 unsigned len)
108{ 812{
109 return zlib_inflateInit2_(z, DEF_WBITS, version, stream_size); 813 unsigned got;
814 unsigned next;
815
816 got = *have;
817 next = 0;
818 while (next < len && got < 4) {
819 if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
820 got++;
821 else if (buf[next])
822 got = 0;
823 else
824 got = 4 - got;
825 next++;
826 }
827 *have = got;
828 return next;
110} 829}
830#endif
111 831
112#undef NEEDBYTE 832#if 0
113#undef NEXTBYTE 833int zlib_inflateSync(z_streamp strm)
114#define NEEDBYTE {if(z->avail_in==0)goto empty;r=trv;} 834{
115#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) 835 unsigned len; /* number of bytes to look at or looked at */
836 unsigned long in, out; /* temporary to save total_in and total_out */
837 unsigned char buf[4]; /* to restore bit buffer to byte string */
838 struct inflate_state *state;
839
840 /* check parameters */
841 if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
842 state = (struct inflate_state *)strm->state;
843 if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
844
845 /* if first time, start search in bit buffer */
846 if (state->mode != SYNC) {
847 state->mode = SYNC;
848 state->hold <<= state->bits & 7;
849 state->bits -= state->bits & 7;
850 len = 0;
851 while (state->bits >= 8) {
852 buf[len++] = (unsigned char)(state->hold);
853 state->hold >>= 8;
854 state->bits -= 8;
855 }
856 state->have = 0;
857 zlib_syncsearch(&(state->have), buf, len);
858 }
859
860 /* search available input */
861 len = zlib_syncsearch(&(state->have), strm->next_in, strm->avail_in);
862 strm->avail_in -= len;
863 strm->next_in += len;
864 strm->total_in += len;
865
866 /* return no joy or set up to restart inflate() on a new block */
867 if (state->have != 4) return Z_DATA_ERROR;
868 in = strm->total_in; out = strm->total_out;
869 zlib_inflateReset(strm);
870 strm->total_in = in; strm->total_out = out;
871 state->mode = TYPE;
872 return Z_OK;
873}
874#endif
116 875
117int zlib_inflate( 876/*
118 z_streamp z, 877 * This subroutine adds the data at next_in/avail_in to the output history
119 int f 878 * without performing any output. The output buffer must be "caught up";
120) 879 * i.e. no pending output but this should always be the case. The state must
880 * be waiting on the start of a block (i.e. mode == TYPE or HEAD). On exit,
881 * the output will also be caught up, and the checksum will have been updated
882 * if need be.
883 */
884int zlib_inflateIncomp(z_stream *z)
121{ 885{
122 int r, trv; 886 struct inflate_state *state = (struct inflate_state *)z->state;
123 uInt b; 887 Byte *saved_no = z->next_out;
124 888 uInt saved_ao = z->avail_out;
125 if (z == NULL || z->state == NULL || z->next_in == NULL) 889
126 return Z_STREAM_ERROR; 890 if (state->mode != TYPE && state->mode != HEAD)
127 trv = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; 891 return Z_DATA_ERROR;
128 r = Z_BUF_ERROR; 892
129 while (1) switch (z->state->mode) 893 /* Setup some variables to allow misuse of updateWindow */
130 { 894 z->avail_out = 0;
131 case METHOD: 895 z->next_out = z->next_in + z->avail_in;
132 NEEDBYTE 896
133 if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) 897 zlib_updatewindow(z, z->avail_in);
134 { 898
135 z->state->mode = I_BAD; 899 /* Restore saved variables */
136 z->msg = (char*)"unknown compression method"; 900 z->avail_out = saved_ao;
137 z->state->sub.marker = 5; /* can't try inflateSync */ 901 z->next_out = saved_no;
138 break; 902
139 } 903 z->adler = state->check =
140 if ((z->state->sub.method >> 4) + 8 > z->state->wbits) 904 UPDATE(state->check, z->next_in, z->avail_in);
141 { 905
142 z->state->mode = I_BAD; 906 z->total_out += z->avail_in;
143 z->msg = (char*)"invalid window size"; 907 z->total_in += z->avail_in;
144 z->state->sub.marker = 5; /* can't try inflateSync */ 908 z->next_in += z->avail_in;
145 break; 909 state->total += z->avail_in;
146 } 910 z->avail_in = 0;
147 z->state->mode = FLAG; 911
148 case FLAG: 912 return Z_OK;
149 NEEDBYTE
150 b = NEXTBYTE;
151 if (((z->state->sub.method << 8) + b) % 31)
152 {
153 z->state->mode = I_BAD;
154 z->msg = (char*)"incorrect header check";
155 z->state->sub.marker = 5; /* can't try inflateSync */
156 break;
157 }
158 if (!(b & PRESET_DICT))
159 {
160 z->state->mode = BLOCKS;
161 break;
162 }
163 z->state->mode = DICT4;
164 case DICT4:
165 NEEDBYTE
166 z->state->sub.check.need = (uLong)NEXTBYTE << 24;
167 z->state->mode = DICT3;
168 case DICT3:
169 NEEDBYTE
170 z->state->sub.check.need += (uLong)NEXTBYTE << 16;
171 z->state->mode = DICT2;
172 case DICT2:
173 NEEDBYTE
174 z->state->sub.check.need += (uLong)NEXTBYTE << 8;
175 z->state->mode = DICT1;
176 case DICT1:
177 NEEDBYTE
178 z->state->sub.check.need += (uLong)NEXTBYTE;
179 z->adler = z->state->sub.check.need;
180 z->state->mode = DICT0;
181 return Z_NEED_DICT;
182 case DICT0:
183 z->state->mode = I_BAD;
184 z->msg = (char*)"need dictionary";
185 z->state->sub.marker = 0; /* can try inflateSync */
186 return Z_STREAM_ERROR;
187 case BLOCKS:
188 r = zlib_inflate_blocks(z->state->blocks, z, r);
189 if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
190 r = zlib_inflate_packet_flush(z->state->blocks);
191 if (r == Z_DATA_ERROR)
192 {
193 z->state->mode = I_BAD;
194 z->state->sub.marker = 0; /* can try inflateSync */
195 break;
196 }
197 if (r == Z_OK)
198 r = trv;
199 if (r != Z_STREAM_END)
200 return r;
201 r = trv;
202 zlib_inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
203 if (z->state->nowrap)
204 {
205 z->state->mode = I_DONE;
206 break;
207 }
208 z->state->mode = CHECK4;
209 case CHECK4:
210 NEEDBYTE
211 z->state->sub.check.need = (uLong)NEXTBYTE << 24;
212 z->state->mode = CHECK3;
213 case CHECK3:
214 NEEDBYTE
215 z->state->sub.check.need += (uLong)NEXTBYTE << 16;
216 z->state->mode = CHECK2;
217 case CHECK2:
218 NEEDBYTE
219 z->state->sub.check.need += (uLong)NEXTBYTE << 8;
220 z->state->mode = CHECK1;
221 case CHECK1:
222 NEEDBYTE
223 z->state->sub.check.need += (uLong)NEXTBYTE;
224
225 if (z->state->sub.check.was != z->state->sub.check.need)
226 {
227 z->state->mode = I_BAD;
228 z->msg = (char*)"incorrect data check";
229 z->state->sub.marker = 5; /* can't try inflateSync */
230 break;
231 }
232 z->state->mode = I_DONE;
233 case I_DONE:
234 return Z_STREAM_END;
235 case I_BAD:
236 return Z_DATA_ERROR;
237 default:
238 return Z_STREAM_ERROR;
239 }
240 empty:
241 if (f != Z_PACKET_FLUSH)
242 return r;
243 z->state->mode = I_BAD;
244 z->msg = (char *)"need more for packet flush";
245 z->state->sub.marker = 0; /* can try inflateSync */
246 return Z_DATA_ERROR;
247} 913}
diff --git a/lib/zlib_inflate/inflate.h b/lib/zlib_inflate/inflate.h
new file mode 100644
index 000000000000..df8a6c92052d
--- /dev/null
+++ b/lib/zlib_inflate/inflate.h
@@ -0,0 +1,107 @@
1/* inflate.h -- internal inflate state definition
2 * Copyright (C) 1995-2004 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/* WARNING: this file should *not* be used by applications. It is
7 part of the implementation of the compression library and is
8 subject to change. Applications should only use zlib.h.
9 */
10
11/* Possible inflate modes between inflate() calls */
12typedef enum {
13 HEAD, /* i: waiting for magic header */
14 FLAGS, /* i: waiting for method and flags (gzip) */
15 TIME, /* i: waiting for modification time (gzip) */
16 OS, /* i: waiting for extra flags and operating system (gzip) */
17 EXLEN, /* i: waiting for extra length (gzip) */
18 EXTRA, /* i: waiting for extra bytes (gzip) */
19 NAME, /* i: waiting for end of file name (gzip) */
20 COMMENT, /* i: waiting for end of comment (gzip) */
21 HCRC, /* i: waiting for header crc (gzip) */
22 DICTID, /* i: waiting for dictionary check value */
23 DICT, /* waiting for inflateSetDictionary() call */
24 TYPE, /* i: waiting for type bits, including last-flag bit */
25 TYPEDO, /* i: same, but skip check to exit inflate on new block */
26 STORED, /* i: waiting for stored size (length and complement) */
27 COPY, /* i/o: waiting for input or output to copy stored block */
28 TABLE, /* i: waiting for dynamic block table lengths */
29 LENLENS, /* i: waiting for code length code lengths */
30 CODELENS, /* i: waiting for length/lit and distance code lengths */
31 LEN, /* i: waiting for length/lit code */
32 LENEXT, /* i: waiting for length extra bits */
33 DIST, /* i: waiting for distance code */
34 DISTEXT, /* i: waiting for distance extra bits */
35 MATCH, /* o: waiting for output space to copy string */
36 LIT, /* o: waiting for output space to write literal */
37 CHECK, /* i: waiting for 32-bit check value */
38 LENGTH, /* i: waiting for 32-bit length (gzip) */
39 DONE, /* finished check, done -- remain here until reset */
40 BAD, /* got a data error -- remain here until reset */
41 MEM, /* got an inflate() memory error -- remain here until reset */
42 SYNC /* looking for synchronization bytes to restart inflate() */
43} inflate_mode;
44
45/*
46 State transitions between above modes -
47
48 (most modes can go to the BAD or MEM mode -- not shown for clarity)
49
50 Process header:
51 HEAD -> (gzip) or (zlib)
52 (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
53 NAME -> COMMENT -> HCRC -> TYPE
54 (zlib) -> DICTID or TYPE
55 DICTID -> DICT -> TYPE
56 Read deflate blocks:
57 TYPE -> STORED or TABLE or LEN or CHECK
58 STORED -> COPY -> TYPE
59 TABLE -> LENLENS -> CODELENS -> LEN
60 Read deflate codes:
61 LEN -> LENEXT or LIT or TYPE
62 LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
63 LIT -> LEN
64 Process trailer:
65 CHECK -> LENGTH -> DONE
66 */
67
68/* state maintained between inflate() calls. Approximately 7K bytes. */
69struct inflate_state {
70 inflate_mode mode; /* current inflate mode */
71 int last; /* true if processing last block */
72 int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
73 int havedict; /* true if dictionary provided */
74 int flags; /* gzip header method and flags (0 if zlib) */
75 unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
76 unsigned long check; /* protected copy of check value */
77 unsigned long total; /* protected copy of output count */
78 /* gz_headerp head; */ /* where to save gzip header information */
79 /* sliding window */
80 unsigned wbits; /* log base 2 of requested window size */
81 unsigned wsize; /* window size or zero if not using window */
82 unsigned whave; /* valid bytes in the window */
83 unsigned write; /* window write index */
84 unsigned char *window; /* allocated sliding window, if needed */
85 /* bit accumulator */
86 unsigned long hold; /* input bit accumulator */
87 unsigned bits; /* number of bits in "in" */
88 /* for string and stored block copying */
89 unsigned length; /* literal or length of data to copy */
90 unsigned offset; /* distance back to copy string from */
91 /* for table and code decoding */
92 unsigned extra; /* extra bits needed */
93 /* fixed and dynamic code tables */
94 code const *lencode; /* starting table for length/literal codes */
95 code const *distcode; /* starting table for distance codes */
96 unsigned lenbits; /* index bits for lencode */
97 unsigned distbits; /* index bits for distcode */
98 /* dynamic table building */
99 unsigned ncode; /* number of code length code lengths */
100 unsigned nlen; /* number of length code lengths */
101 unsigned ndist; /* number of distance code lengths */
102 unsigned have; /* number of code lengths in lens[] */
103 code *next; /* next available space in codes[] */
104 unsigned short lens[320]; /* temporary storage for code lengths */
105 unsigned short work[288]; /* work area for code table building */
106 code codes[ENOUGH]; /* space for code tables */
107};
diff --git a/lib/zlib_inflate/inflate_syms.c b/lib/zlib_inflate/inflate_syms.c
index ef49738f57ec..2061d4f06765 100644
--- a/lib/zlib_inflate/inflate_syms.c
+++ b/lib/zlib_inflate/inflate_syms.c
@@ -12,8 +12,7 @@
12 12
13EXPORT_SYMBOL(zlib_inflate_workspacesize); 13EXPORT_SYMBOL(zlib_inflate_workspacesize);
14EXPORT_SYMBOL(zlib_inflate); 14EXPORT_SYMBOL(zlib_inflate);
15EXPORT_SYMBOL(zlib_inflateInit_); 15EXPORT_SYMBOL(zlib_inflateInit2);
16EXPORT_SYMBOL(zlib_inflateInit2_);
17EXPORT_SYMBOL(zlib_inflateEnd); 16EXPORT_SYMBOL(zlib_inflateEnd);
18EXPORT_SYMBOL(zlib_inflateReset); 17EXPORT_SYMBOL(zlib_inflateReset);
19EXPORT_SYMBOL(zlib_inflateIncomp); 18EXPORT_SYMBOL(zlib_inflateIncomp);
diff --git a/lib/zlib_inflate/inflate_sync.c b/lib/zlib_inflate/inflate_sync.c
deleted file mode 100644
index 61411ff89d61..000000000000
--- a/lib/zlib_inflate/inflate_sync.c
+++ /dev/null
@@ -1,152 +0,0 @@
1/* inflate.c -- zlib interface to inflate modules
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include <linux/zutil.h>
7#include "infblock.h"
8#include "infutil.h"
9
10#if 0
11int zlib_inflateSync(
12 z_streamp z
13)
14{
15 uInt n; /* number of bytes to look at */
16 Byte *p; /* pointer to bytes */
17 uInt m; /* number of marker bytes found in a row */
18 uLong r, w; /* temporaries to save total_in and total_out */
19
20 /* set up */
21 if (z == NULL || z->state == NULL)
22 return Z_STREAM_ERROR;
23 if (z->state->mode != I_BAD)
24 {
25 z->state->mode = I_BAD;
26 z->state->sub.marker = 0;
27 }
28 if ((n = z->avail_in) == 0)
29 return Z_BUF_ERROR;
30 p = z->next_in;
31 m = z->state->sub.marker;
32
33 /* search */
34 while (n && m < 4)
35 {
36 static const Byte mark[4] = {0, 0, 0xff, 0xff};
37 if (*p == mark[m])
38 m++;
39 else if (*p)
40 m = 0;
41 else
42 m = 4 - m;
43 p++, n--;
44 }
45
46 /* restore */
47 z->total_in += p - z->next_in;
48 z->next_in = p;
49 z->avail_in = n;
50 z->state->sub.marker = m;
51
52 /* return no joy or set up to restart on a new block */
53 if (m != 4)
54 return Z_DATA_ERROR;
55 r = z->total_in; w = z->total_out;
56 zlib_inflateReset(z);
57 z->total_in = r; z->total_out = w;
58 z->state->mode = BLOCKS;
59 return Z_OK;
60}
61#endif /* 0 */
62
63
64/* Returns true if inflate is currently at the end of a block generated
65 * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
66 * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
67 * but removes the length bytes of the resulting empty stored block. When
68 * decompressing, PPP checks that at the end of input packet, inflate is
69 * waiting for these length bytes.
70 */
71#if 0
72int zlib_inflateSyncPoint(
73 z_streamp z
74)
75{
76 if (z == NULL || z->state == NULL || z->state->blocks == NULL)
77 return Z_STREAM_ERROR;
78 return zlib_inflate_blocks_sync_point(z->state->blocks);
79}
80#endif /* 0 */
81
82/*
83 * This subroutine adds the data at next_in/avail_in to the output history
84 * without performing any output. The output buffer must be "caught up";
85 * i.e. no pending output (hence s->read equals s->write), and the state must
86 * be BLOCKS (i.e. we should be willing to see the start of a series of
87 * BLOCKS). On exit, the output will also be caught up, and the checksum
88 * will have been updated if need be.
89 */
90static int zlib_inflate_addhistory(inflate_blocks_statef *s,
91 z_stream *z)
92{
93 uLong b; /* bit buffer */ /* NOT USED HERE */
94 uInt k; /* bits in bit buffer */ /* NOT USED HERE */
95 uInt t; /* temporary storage */
96 Byte *p; /* input data pointer */
97 uInt n; /* bytes available there */
98 Byte *q; /* output window write pointer */
99 uInt m; /* bytes to end of window or read pointer */
100
101 if (s->read != s->write)
102 return Z_STREAM_ERROR;
103 if (s->mode != TYPE)
104 return Z_DATA_ERROR;
105
106 /* we're ready to rock */
107 LOAD
108 /* while there is input ready, copy to output buffer, moving
109 * pointers as needed.
110 */
111 while (n) {
112 t = n; /* how many to do */
113 /* is there room until end of buffer? */
114 if (t > m) t = m;
115 /* update check information */
116 if (s->checkfn != NULL)
117 s->check = (*s->checkfn)(s->check, q, t);
118 memcpy(q, p, t);
119 q += t;
120 p += t;
121 n -= t;
122 z->total_out += t;
123 s->read = q; /* drag read pointer forward */
124/* WWRAP */ /* expand WWRAP macro by hand to handle s->read */
125 if (q == s->end) {
126 s->read = q = s->window;
127 m = WAVAIL;
128 }
129 }
130 UPDATE
131 return Z_OK;
132}
133
134
135/*
136 * This subroutine adds the data at next_in/avail_in to the output history
137 * without performing any output. The output buffer must be "caught up";
138 * i.e. no pending output (hence s->read equals s->write), and the state must
139 * be BLOCKS (i.e. we should be willing to see the start of a series of
140 * BLOCKS). On exit, the output will also be caught up, and the checksum
141 * will have been updated if need be.
142 */
143
144int zlib_inflateIncomp(
145 z_stream *z
146
147)
148{
149 if (z->state->mode != BLOCKS)
150 return Z_DATA_ERROR;
151 return zlib_inflate_addhistory(z->state->blocks, z);
152}
diff --git a/lib/zlib_inflate/inftrees.c b/lib/zlib_inflate/inftrees.c
index 874950ec4858..62343c53bf7e 100644
--- a/lib/zlib_inflate/inftrees.c
+++ b/lib/zlib_inflate/inftrees.c
@@ -1,412 +1,329 @@
1/* inftrees.c -- generate Huffman trees for efficient decoding 1/* inftrees.c -- generate Huffman trees for efficient decoding
2 * Copyright (C) 1995-1998 Mark Adler 2 * Copyright (C) 1995-2005 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
6#include <linux/zutil.h> 6#include <linux/zutil.h>
7#include "inftrees.h" 7#include "inftrees.h"
8#include "infutil.h"
9 8
10static const char inflate_copyright[] __attribute_used__ = 9#define MAXBITS 15
11 " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; 10
11const char inflate_copyright[] =
12 " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
12/* 13/*
13 If you use the zlib library in a product, an acknowledgment is welcome 14 If you use the zlib library in a product, an acknowledgment is welcome
14 in the documentation of your product. If for some reason you cannot 15 in the documentation of your product. If for some reason you cannot
15 include such an acknowledgment, I would appreciate that you keep this 16 include such an acknowledgment, I would appreciate that you keep this
16 copyright string in the executable of your product. 17 copyright string in the executable of your product.
17 */ 18 */
18struct internal_state;
19
20/* simplify the use of the inflate_huft type with some defines */
21#define exop word.what.Exop
22#define bits word.what.Bits
23
24
25static int huft_build (
26 uInt *, /* code lengths in bits */
27 uInt, /* number of codes */
28 uInt, /* number of "simple" codes */
29 const uInt *, /* list of base values for non-simple codes */
30 const uInt *, /* list of extra bits for non-simple codes */
31 inflate_huft **, /* result: starting table */
32 uInt *, /* maximum lookup bits (returns actual) */
33 inflate_huft *, /* space for trees */
34 uInt *, /* hufts used in space */
35 uInt * ); /* space for values */
36
37/* Tables for deflate from PKZIP's appnote.txt. */
38static const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
39 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
40 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
41 /* see note #13 above about 258 */
42static const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
43 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
44 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
45static const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
46 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
47 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
48 8193, 12289, 16385, 24577};
49static const uInt cpdext[30] = { /* Extra bits for distance codes */
50 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
51 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
52 12, 12, 13, 13};
53 19
54/* 20/*
55 Huffman code decoding is performed using a multi-level table lookup. 21 Build a set of tables to decode the provided canonical Huffman code.
56 The fastest way to decode is to simply build a lookup table whose 22 The code lengths are lens[0..codes-1]. The result starts at *table,
57 size is determined by the longest code. However, the time it takes 23 whose indices are 0..2^bits-1. work is a writable array of at least
58 to build this table can also be a factor if the data being decoded 24 lens shorts, which is used as a work area. type is the type of code
59 is not very long. The most common codes are necessarily the 25 to be generated, CODES, LENS, or DISTS. On return, zero is success,
60 shortest codes, so those codes dominate the decoding time, and hence 26 -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
61 the speed. The idea is you can have a shorter table that decodes the 27 on return points to the next available entry's address. bits is the
62 shorter, more probable codes, and then point to subsidiary tables for 28 requested root table index bits, and on return it is the actual root
63 the longer codes. The time it costs to decode the longer codes is 29 table index bits. It will differ if the request is greater than the
64 then traded against the time it takes to make longer tables. 30 longest code or if it is less than the shortest code.
65
66 This results of this trade are in the variables lbits and dbits
67 below. lbits is the number of bits the first level table for literal/
68 length codes can decode in one step, and dbits is the same thing for
69 the distance codes. Subsequent tables are also less than or equal to
70 those sizes. These values may be adjusted either when all of the
71 codes are shorter than that, in which case the longest code length in
72 bits is used, or when the shortest code is *longer* than the requested
73 table size, in which case the length of the shortest code in bits is
74 used.
75
76 There are two different values for the two tables, since they code a
77 different number of possibilities each. The literal/length table
78 codes 286 possible values, or in a flat code, a little over eight
79 bits. The distance table codes 30 possible values, or a little less
80 than five bits, flat. The optimum values for speed end up being
81 about one bit more than those, so lbits is 8+1 and dbits is 5+1.
82 The optimum values may differ though from machine to machine, and
83 possibly even between compilers. Your mileage may vary.
84 */ 31 */
85 32int zlib_inflate_table(type, lens, codes, table, bits, work)
86 33codetype type;
87/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ 34unsigned short *lens;
88#define BMAX 15 /* maximum bit length of any code */ 35unsigned codes;
89 36code **table;
90static int huft_build( 37unsigned *bits;
91 uInt *b, /* code lengths in bits (all assumed <= BMAX) */ 38unsigned short *work;
92 uInt n, /* number of codes (assumed <= 288) */
93 uInt s, /* number of simple-valued codes (0..s-1) */
94 const uInt *d, /* list of base values for non-simple codes */
95 const uInt *e, /* list of extra bits for non-simple codes */
96 inflate_huft **t, /* result: starting table */
97 uInt *m, /* maximum lookup bits, returns actual */
98 inflate_huft *hp, /* space for trees */
99 uInt *hn, /* hufts used in space */
100 uInt *v /* working area: values in order of bit length */
101)
102/* Given a list of code lengths and a maximum table size, make a set of
103 tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
104 if the given code set is incomplete (the tables are still built in this
105 case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
106 lengths), or Z_MEM_ERROR if not enough memory. */
107{ 39{
40 unsigned len; /* a code's length in bits */
41 unsigned sym; /* index of code symbols */
42 unsigned min, max; /* minimum and maximum code lengths */
43 unsigned root; /* number of index bits for root table */
44 unsigned curr; /* number of index bits for current table */
45 unsigned drop; /* code bits to drop for sub-table */
46 int left; /* number of prefix codes available */
47 unsigned used; /* code entries in table used */
48 unsigned huff; /* Huffman code */
49 unsigned incr; /* for incrementing code, index */
50 unsigned fill; /* index for replicating entries */
51 unsigned low; /* low bits for current root entry */
52 unsigned mask; /* mask for low root bits */
53 code this; /* table entry for duplication */
54 code *next; /* next available space in table */
55 const unsigned short *base; /* base value table to use */
56 const unsigned short *extra; /* extra bits table to use */
57 int end; /* use base and extra for symbol > end */
58 unsigned short count[MAXBITS+1]; /* number of codes of each length */
59 unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
60 static const unsigned short lbase[31] = { /* Length codes 257..285 base */
61 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
62 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
63 static const unsigned short lext[31] = { /* Length codes 257..285 extra */
64 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
65 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
66 static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
67 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
68 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
69 8193, 12289, 16385, 24577, 0, 0};
70 static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
71 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
72 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
73 28, 28, 29, 29, 64, 64};
74
75 /*
76 Process a set of code lengths to create a canonical Huffman code. The
77 code lengths are lens[0..codes-1]. Each length corresponds to the
78 symbols 0..codes-1. The Huffman code is generated by first sorting the
79 symbols by length from short to long, and retaining the symbol order
80 for codes with equal lengths. Then the code starts with all zero bits
81 for the first code of the shortest length, and the codes are integer
82 increments for the same length, and zeros are appended as the length
83 increases. For the deflate format, these bits are stored backwards
84 from their more natural integer increment ordering, and so when the
85 decoding tables are built in the large loop below, the integer codes
86 are incremented backwards.
87
88 This routine assumes, but does not check, that all of the entries in
89 lens[] are in the range 0..MAXBITS. The caller must assure this.
90 1..MAXBITS is interpreted as that code length. zero means that that
91 symbol does not occur in this code.
92
93 The codes are sorted by computing a count of codes for each length,
94 creating from that a table of starting indices for each length in the
95 sorted table, and then entering the symbols in order in the sorted
96 table. The sorted table is work[], with that space being provided by
97 the caller.
98
99 The length counts are used for other purposes as well, i.e. finding
100 the minimum and maximum length codes, determining if there are any
101 codes at all, checking for a valid set of lengths, and looking ahead
102 at length counts to determine sub-table sizes when building the
103 decoding tables.
104 */
105
106 /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
107 for (len = 0; len <= MAXBITS; len++)
108 count[len] = 0;
109 for (sym = 0; sym < codes; sym++)
110 count[lens[sym]]++;
111
112 /* bound code lengths, force root to be within code lengths */
113 root = *bits;
114 for (max = MAXBITS; max >= 1; max--)
115 if (count[max] != 0) break;
116 if (root > max) root = max;
117 if (max == 0) { /* no symbols to code at all */
118 this.op = (unsigned char)64; /* invalid code marker */
119 this.bits = (unsigned char)1;
120 this.val = (unsigned short)0;
121 *(*table)++ = this; /* make a table to force an error */
122 *(*table)++ = this;
123 *bits = 1;
124 return 0; /* no symbols, but wait for decoding to report error */
125 }
126 for (min = 1; min <= MAXBITS; min++)
127 if (count[min] != 0) break;
128 if (root < min) root = min;
129
130 /* check for an over-subscribed or incomplete set of lengths */
131 left = 1;
132 for (len = 1; len <= MAXBITS; len++) {
133 left <<= 1;
134 left -= count[len];
135 if (left < 0) return -1; /* over-subscribed */
136 }
137 if (left > 0 && (type == CODES || max != 1))
138 return -1; /* incomplete set */
139
140 /* generate offsets into symbol table for each length for sorting */
141 offs[1] = 0;
142 for (len = 1; len < MAXBITS; len++)
143 offs[len + 1] = offs[len] + count[len];
144
145 /* sort symbols by length, by symbol order within each length */
146 for (sym = 0; sym < codes; sym++)
147 if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
148
149 /*
150 Create and fill in decoding tables. In this loop, the table being
151 filled is at next and has curr index bits. The code being used is huff
152 with length len. That code is converted to an index by dropping drop
153 bits off of the bottom. For codes where len is less than drop + curr,
154 those top drop + curr - len bits are incremented through all values to
155 fill the table with replicated entries.
156
157 root is the number of index bits for the root table. When len exceeds
158 root, sub-tables are created pointed to by the root entry with an index
159 of the low root bits of huff. This is saved in low to check for when a
160 new sub-table should be started. drop is zero when the root table is
161 being filled, and drop is root when sub-tables are being filled.
162
163 When a new sub-table is needed, it is necessary to look ahead in the
164 code lengths to determine what size sub-table is needed. The length
165 counts are used for this, and so count[] is decremented as codes are
166 entered in the tables.
167
168 used keeps track of how many table entries have been allocated from the
169 provided *table space. It is checked when a LENS table is being made
170 against the space in *table, ENOUGH, minus the maximum space needed by
171 the worst case distance code, MAXD. This should never happen, but the
172 sufficiency of ENOUGH has not been proven exhaustively, hence the check.
173 This assumes that when type == LENS, bits == 9.
174
175 sym increments through all symbols, and the loop terminates when
176 all codes of length max, i.e. all codes, have been processed. This
177 routine permits incomplete codes, so another loop after this one fills
178 in the rest of the decoding tables with invalid code markers.
179 */
180
181 /* set up for code type */
182 switch (type) {
183 case CODES:
184 base = extra = work; /* dummy value--not used */
185 end = 19;
186 break;
187 case LENS:
188 base = lbase;
189 base -= 257;
190 extra = lext;
191 extra -= 257;
192 end = 256;
193 break;
194 default: /* DISTS */
195 base = dbase;
196 extra = dext;
197 end = -1;
198 }
108 199
109 uInt a; /* counter for codes of length k */ 200 /* initialize state for loop */
110 uInt c[BMAX+1]; /* bit length count table */ 201 huff = 0; /* starting code */
111 uInt f; /* i repeats in table every f entries */ 202 sym = 0; /* starting code symbol */
112 int g; /* maximum code length */ 203 len = min; /* starting code length */
113 int h; /* table level */ 204 next = *table; /* current table to fill in */
114 register uInt i; /* counter, current code */ 205 curr = root; /* current table index bits */
115 register uInt j; /* counter */ 206 drop = 0; /* current bits to drop from code for index */
116 register int k; /* number of bits in current code */ 207 low = (unsigned)(-1); /* trigger new sub-table when len > root */
117 int l; /* bits per table (returned in m) */ 208 used = 1U << root; /* use root table entries */
118 uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ 209 mask = used - 1; /* mask for comparing low */
119 register uInt *p; /* pointer into c[], b[], or v[] */ 210
120 inflate_huft *q; /* points to current table */ 211 /* check available table space */
121 struct inflate_huft_s r; /* table entry for structure assignment */ 212 if (type == LENS && used >= ENOUGH - MAXD)
122 inflate_huft *u[BMAX]; /* table stack */ 213 return 1;
123 register int w; /* bits before this table == (l * h) */ 214
124 uInt x[BMAX+1]; /* bit offsets, then code stack */ 215 /* process all codes and make table entries */
125 uInt *xp; /* pointer into x */ 216 for (;;) {
126 int y; /* number of dummy codes added */ 217 /* create table entry */
127 uInt z; /* number of entries in current table */ 218 this.bits = (unsigned char)(len - drop);
128 219 if ((int)(work[sym]) < end) {
129 220 this.op = (unsigned char)0;
130 /* Generate counts for each bit length */ 221 this.val = work[sym];
131 p = c;
132#define C0 *p++ = 0;
133#define C2 C0 C0 C0 C0
134#define C4 C2 C2 C2 C2
135 C4 /* clear c[]--assume BMAX+1 is 16 */
136 p = b; i = n;
137 do {
138 c[*p++]++; /* assume all entries <= BMAX */
139 } while (--i);
140 if (c[0] == n) /* null input--all zero length codes */
141 {
142 *t = NULL;
143 *m = 0;
144 return Z_OK;
145 }
146
147
148 /* Find minimum and maximum length, bound *m by those */
149 l = *m;
150 for (j = 1; j <= BMAX; j++)
151 if (c[j])
152 break;
153 k = j; /* minimum code length */
154 if ((uInt)l < j)
155 l = j;
156 for (i = BMAX; i; i--)
157 if (c[i])
158 break;
159 g = i; /* maximum code length */
160 if ((uInt)l > i)
161 l = i;
162 *m = l;
163
164
165 /* Adjust last length count to fill out codes, if needed */
166 for (y = 1 << j; j < i; j++, y <<= 1)
167 if ((y -= c[j]) < 0)
168 return Z_DATA_ERROR;
169 if ((y -= c[i]) < 0)
170 return Z_DATA_ERROR;
171 c[i] += y;
172
173
174 /* Generate starting offsets into the value table for each length */
175 x[1] = j = 0;
176 p = c + 1; xp = x + 2;
177 while (--i) { /* note that i == g from above */
178 *xp++ = (j += *p++);
179 }
180
181
182 /* Make a table of values in order of bit lengths */
183 p = b; i = 0;
184 do {
185 if ((j = *p++) != 0)
186 v[x[j]++] = i;
187 } while (++i < n);
188 n = x[g]; /* set n to length of v */
189
190
191 /* Generate the Huffman codes and for each, make the table entries */
192 x[0] = i = 0; /* first Huffman code is zero */
193 p = v; /* grab values in bit order */
194 h = -1; /* no tables yet--level -1 */
195 w = -l; /* bits decoded == (l * h) */
196 u[0] = NULL; /* just to keep compilers happy */
197 q = NULL; /* ditto */
198 z = 0; /* ditto */
199
200 /* go through the bit lengths (k already is bits in shortest code) */
201 for (; k <= g; k++)
202 {
203 a = c[k];
204 while (a--)
205 {
206 /* here i is the Huffman code of length k bits for value *p */
207 /* make tables up to required level */
208 while (k > w + l)
209 {
210 h++;
211 w += l; /* previous table always l bits */
212
213 /* compute minimum size table less than or equal to l bits */
214 z = g - w;
215 z = z > (uInt)l ? l : z; /* table size upper limit */
216 if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
217 { /* too few codes for k-w bit table */
218 f -= a + 1; /* deduct codes from patterns left */
219 xp = c + k;
220 if (j < z)
221 while (++j < z) /* try smaller tables up to z bits */
222 {
223 if ((f <<= 1) <= *++xp)
224 break; /* enough codes to use up j bits */
225 f -= *xp; /* else deduct codes from patterns */
226 }
227 } 222 }
228 z = 1 << j; /* table entries for j-bit table */ 223 else if ((int)(work[sym]) > end) {
229 224 this.op = (unsigned char)(extra[work[sym]]);
230 /* allocate new table */ 225 this.val = base[work[sym]];
231 if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ 226 }
232 return Z_DATA_ERROR; /* overflow of MANY */ 227 else {
233 u[h] = q = hp + *hn; 228 this.op = (unsigned char)(32 + 64); /* end of block */
234 *hn += z; 229 this.val = 0;
235
236 /* connect to last table, if there is one */
237 if (h)
238 {
239 x[h] = i; /* save pattern for backing up */
240 r.bits = (Byte)l; /* bits to dump before this table */
241 r.exop = (Byte)j; /* bits in this table */
242 j = i >> (w - l);
243 r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
244 u[h-1][j] = r; /* connect to last table */
245 } 230 }
246 else
247 *t = q; /* first table is returned result */
248 }
249
250 /* set up table entry in r */
251 r.bits = (Byte)(k - w);
252 if (p >= v + n)
253 r.exop = 128 + 64; /* out of values--invalid code */
254 else if (*p < s)
255 {
256 r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
257 r.base = *p++; /* simple code is just the value */
258 }
259 else
260 {
261 r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
262 r.base = d[*p++ - s];
263 }
264
265 /* fill code-like entries with r */
266 f = 1 << (k - w);
267 for (j = i >> w; j < z; j += f)
268 q[j] = r;
269
270 /* backwards increment the k-bit code i */
271 for (j = 1 << (k - 1); i & j; j >>= 1)
272 i ^= j;
273 i ^= j;
274
275 /* backup over finished tables */
276 mask = (1 << w) - 1; /* needed on HP, cc -O bug */
277 while ((i & mask) != x[h])
278 {
279 h--; /* don't need to update q */
280 w -= l;
281 mask = (1 << w) - 1;
282 }
283 }
284 }
285 231
232 /* replicate for those indices with low len bits equal to huff */
233 incr = 1U << (len - drop);
234 fill = 1U << curr;
235 min = fill; /* save offset to next table */
236 do {
237 fill -= incr;
238 next[(huff >> drop) + fill] = this;
239 } while (fill != 0);
240
241 /* backwards increment the len-bit code huff */
242 incr = 1U << (len - 1);
243 while (huff & incr)
244 incr >>= 1;
245 if (incr != 0) {
246 huff &= incr - 1;
247 huff += incr;
248 }
249 else
250 huff = 0;
286 251
287 /* Return Z_BUF_ERROR if we were given an incomplete table */ 252 /* go to next symbol, update count, len */
288 return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; 253 sym++;
289} 254 if (--(count[len]) == 0) {
255 if (len == max) break;
256 len = lens[work[sym]];
257 }
290 258
259 /* create new sub-table if needed */
260 if (len > root && (huff & mask) != low) {
261 /* if first time, transition to sub-tables */
262 if (drop == 0)
263 drop = root;
264
265 /* increment past last table */
266 next += min; /* here min is 1 << curr */
267
268 /* determine length of next table */
269 curr = len - drop;
270 left = (int)(1 << curr);
271 while (curr + drop < max) {
272 left -= count[curr + drop];
273 if (left <= 0) break;
274 curr++;
275 left <<= 1;
276 }
291 277
292int zlib_inflate_trees_bits( 278 /* check for enough space */
293 uInt *c, /* 19 code lengths */ 279 used += 1U << curr;
294 uInt *bb, /* bits tree desired/actual depth */ 280 if (type == LENS && used >= ENOUGH - MAXD)
295 inflate_huft **tb, /* bits tree result */ 281 return 1;
296 inflate_huft *hp, /* space for trees */
297 z_streamp z /* for messages */
298)
299{
300 int r;
301 uInt hn = 0; /* hufts used in space */
302 uInt *v; /* work area for huft_build */
303
304 v = WS(z)->tree_work_area_1;
305 r = huft_build(c, 19, 19, NULL, NULL, tb, bb, hp, &hn, v);
306 if (r == Z_DATA_ERROR)
307 z->msg = (char*)"oversubscribed dynamic bit lengths tree";
308 else if (r == Z_BUF_ERROR || *bb == 0)
309 {
310 z->msg = (char*)"incomplete dynamic bit lengths tree";
311 r = Z_DATA_ERROR;
312 }
313 return r;
314}
315 282
316int zlib_inflate_trees_dynamic( 283 /* point entry in root table to sub-table */
317 uInt nl, /* number of literal/length codes */ 284 low = huff & mask;
318 uInt nd, /* number of distance codes */ 285 (*table)[low].op = (unsigned char)curr;
319 uInt *c, /* that many (total) code lengths */ 286 (*table)[low].bits = (unsigned char)root;
320 uInt *bl, /* literal desired/actual bit depth */ 287 (*table)[low].val = (unsigned short)(next - *table);
321 uInt *bd, /* distance desired/actual bit depth */ 288 }
322 inflate_huft **tl, /* literal/length tree result */
323 inflate_huft **td, /* distance tree result */
324 inflate_huft *hp, /* space for trees */
325 z_streamp z /* for messages */
326)
327{
328 int r;
329 uInt hn = 0; /* hufts used in space */
330 uInt *v; /* work area for huft_build */
331
332 /* allocate work area */
333 v = WS(z)->tree_work_area_2;
334
335 /* build literal/length tree */
336 r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
337 if (r != Z_OK || *bl == 0)
338 {
339 if (r == Z_DATA_ERROR)
340 z->msg = (char*)"oversubscribed literal/length tree";
341 else if (r != Z_MEM_ERROR)
342 {
343 z->msg = (char*)"incomplete literal/length tree";
344 r = Z_DATA_ERROR;
345 }
346 return r;
347 }
348
349 /* build distance tree */
350 r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
351 if (r != Z_OK || (*bd == 0 && nl > 257))
352 {
353 if (r == Z_DATA_ERROR)
354 z->msg = (char*)"oversubscribed distance tree";
355 else if (r == Z_BUF_ERROR) {
356#ifdef PKZIP_BUG_WORKAROUND
357 r = Z_OK;
358 }
359#else
360 z->msg = (char*)"incomplete distance tree";
361 r = Z_DATA_ERROR;
362 }
363 else if (r != Z_MEM_ERROR)
364 {
365 z->msg = (char*)"empty distance tree with lengths";
366 r = Z_DATA_ERROR;
367 } 289 }
368 return r;
369#endif
370 }
371 290
372 /* done */ 291 /*
373 return Z_OK; 292 Fill in rest of table for incomplete codes. This loop is similar to the
374} 293 loop above in incrementing huff for table indices. It is assumed that
294 len is equal to curr + drop, so there is no loop needed to increment
295 through high index bits. When the current sub-table is filled, the loop
296 drops back to the root table to fill in any remaining entries there.
297 */
298 this.op = (unsigned char)64; /* invalid code marker */
299 this.bits = (unsigned char)(len - drop);
300 this.val = (unsigned short)0;
301 while (huff != 0) {
302 /* when done with sub-table, drop back to root table */
303 if (drop != 0 && (huff & mask) != low) {
304 drop = 0;
305 len = root;
306 next = *table;
307 this.bits = (unsigned char)len;
308 }
375 309
310 /* put invalid code marker in table */
311 next[huff >> drop] = this;
376 312
377int zlib_inflate_trees_fixed( 313 /* backwards increment the len-bit code huff */
378 uInt *bl, /* literal desired/actual bit depth */ 314 incr = 1U << (len - 1);
379 uInt *bd, /* distance desired/actual bit depth */ 315 while (huff & incr)
380 inflate_huft **tl, /* literal/length tree result */ 316 incr >>= 1;
381 inflate_huft **td, /* distance tree result */ 317 if (incr != 0) {
382 inflate_huft *hp, /* space for trees */ 318 huff &= incr - 1;
383 z_streamp z /* for memory allocation */ 319 huff += incr;
384) 320 }
385{ 321 else
386 int i; /* temporary variable */ 322 huff = 0;
387 unsigned l[288]; /* length list for huft_build */ 323 }
388 uInt *v; /* work area for huft_build */ 324
389 325 /* set return parameters */
390 /* set up literal table */ 326 *table += used;
391 for (i = 0; i < 144; i++) 327 *bits = root;
392 l[i] = 8; 328 return 0;
393 for (; i < 256; i++)
394 l[i] = 9;
395 for (; i < 280; i++)
396 l[i] = 7;
397 for (; i < 288; i++) /* make a complete, but wrong code set */
398 l[i] = 8;
399 *bl = 9;
400 v = WS(z)->tree_work_area_1;
401 if ((i = huft_build(l, 288, 257, cplens, cplext, tl, bl, hp, &i, v)) != 0)
402 return i;
403
404 /* set up distance table */
405 for (i = 0; i < 30; i++) /* make an incomplete code set */
406 l[i] = 5;
407 *bd = 5;
408 if ((i = huft_build(l, 30, 0, cpdist, cpdext, td, bd, hp, &i, v)) > 1)
409 return i;
410
411 return Z_OK;
412} 329}
diff --git a/lib/zlib_inflate/inftrees.h b/lib/zlib_inflate/inftrees.h
index e37705adc008..5f5219b1240e 100644
--- a/lib/zlib_inflate/inftrees.h
+++ b/lib/zlib_inflate/inftrees.h
@@ -1,6 +1,6 @@
1/* inftrees.h -- header to use inftrees.c 1/* inftrees.h -- header to use inftrees.c
2 * Copyright (C) 1995-1998 Mark Adler 2 * Copyright (C) 1995-2005 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
6/* WARNING: this file should *not* be used by applications. It is 6/* WARNING: this file should *not* be used by applications. It is
@@ -8,57 +8,48 @@
8 subject to change. Applications should only use zlib.h. 8 subject to change. Applications should only use zlib.h.
9 */ 9 */
10 10
11/* Huffman code lookup table entry--this entry is four bytes for machines 11/* Structure for decoding tables. Each entry provides either the
12 that have 16-bit pointers (e.g. PC's in the small or medium model). */ 12 information needed to do the operation requested by the code that
13 13 indexed that table entry, or it provides a pointer to another
14#ifndef _INFTREES_H 14 table that indexes more bits of the code. op indicates whether
15#define _INFTREES_H 15 the entry is a pointer to another table, a literal, a length or
16 16 distance, an end-of-block, or an invalid code. For a table
17typedef struct inflate_huft_s inflate_huft; 17 pointer, the low four bits of op is the number of index bits of
18 18 that table. For a length or distance, the low four bits of op
19struct inflate_huft_s { 19 is the number of extra bits to get after the code. bits is
20 union { 20 the number of bits in this code or part of the code to drop off
21 struct { 21 of the bit buffer. val is the actual byte to output in the case
22 Byte Exop; /* number of extra bits or operation */ 22 of a literal, the base length or distance, or the offset from
23 Byte Bits; /* number of bits in this code or subcode */ 23 the current table to the next table. Each entry is four bytes. */
24 } what; 24typedef struct {
25 uInt pad; /* pad structure to a power of 2 (4 bytes for */ 25 unsigned char op; /* operation, extra bits, table bits */
26 } word; /* 16-bit, 8 bytes for 32-bit int's) */ 26 unsigned char bits; /* bits in this part of the code */
27 uInt base; /* literal, length base, distance base, 27 unsigned short val; /* offset in table or code value */
28 or table offset */ 28} code;
29}; 29
30/* op values as set by inflate_table():
31 00000000 - literal
32 0000tttt - table link, tttt != 0 is the number of table index bits
33 0001eeee - length or distance, eeee is the number of extra bits
34 01100000 - end of block
35 01000000 - invalid code
36 */
30 37
31/* Maximum size of dynamic tree. The maximum found in a long but non- 38/* Maximum size of dynamic tree. The maximum found in a long but non-
32 exhaustive search was 1004 huft structures (850 for length/literals 39 exhaustive search was 1444 code structures (852 for length/literals
33 and 154 for distances, the latter actually the result of an 40 and 592 for distances, the latter actually the result of an
34 exhaustive search). The actual maximum is not known, but the 41 exhaustive search). The true maximum is not known, but the value
35 value below is more than safe. */ 42 below is more than safe. */
36#define MANY 1440 43#define ENOUGH 2048
37 44#define MAXD 592
38extern int zlib_inflate_trees_bits ( 45
39 uInt *, /* 19 code lengths */ 46/* Type of code to build for inftable() */
40 uInt *, /* bits tree desired/actual depth */ 47typedef enum {
41 inflate_huft **, /* bits tree result */ 48 CODES,
42 inflate_huft *, /* space for trees */ 49 LENS,
43 z_streamp); /* for messages */ 50 DISTS
44 51} codetype;
45extern int zlib_inflate_trees_dynamic ( 52
46 uInt, /* number of literal/length codes */ 53extern int zlib_inflate_table (codetype type, unsigned short *lens,
47 uInt, /* number of distance codes */ 54 unsigned codes, code **table,
48 uInt *, /* that many (total) code lengths */ 55 unsigned *bits, unsigned short *work);
49 uInt *, /* literal desired/actual bit depth */
50 uInt *, /* distance desired/actual bit depth */
51 inflate_huft **, /* literal/length tree result */
52 inflate_huft **, /* distance tree result */
53 inflate_huft *, /* space for trees */
54 z_streamp); /* for messages */
55
56extern int zlib_inflate_trees_fixed (
57 uInt *, /* literal desired/actual bit depth */
58 uInt *, /* distance desired/actual bit depth */
59 inflate_huft **, /* literal/length tree result */
60 inflate_huft **, /* distance tree result */
61 inflate_huft *, /* space for trees */
62 z_streamp); /* for memory allocation */
63
64#endif /* _INFTREES_H */
diff --git a/lib/zlib_inflate/infutil.c b/lib/zlib_inflate/infutil.c
deleted file mode 100644
index 00202b3438e1..000000000000
--- a/lib/zlib_inflate/infutil.c
+++ /dev/null
@@ -1,88 +0,0 @@
1/* inflate_util.c -- data and routines common to blocks and codes
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include <linux/zutil.h>
7#include "infblock.h"
8#include "inftrees.h"
9#include "infcodes.h"
10#include "infutil.h"
11
12struct inflate_codes_state;
13
14/* And'ing with mask[n] masks the lower n bits */
15uInt zlib_inflate_mask[17] = {
16 0x0000,
17 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
18 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
19};
20
21
22/* copy as much as possible from the sliding window to the output area */
23int zlib_inflate_flush(
24 inflate_blocks_statef *s,
25 z_streamp z,
26 int r
27)
28{
29 uInt n;
30 Byte *p;
31 Byte *q;
32
33 /* local copies of source and destination pointers */
34 p = z->next_out;
35 q = s->read;
36
37 /* compute number of bytes to copy as far as end of window */
38 n = (uInt)((q <= s->write ? s->write : s->end) - q);
39 if (n > z->avail_out) n = z->avail_out;
40 if (n && r == Z_BUF_ERROR) r = Z_OK;
41
42 /* update counters */
43 z->avail_out -= n;
44 z->total_out += n;
45
46 /* update check information */
47 if (s->checkfn != NULL)
48 z->adler = s->check = (*s->checkfn)(s->check, q, n);
49
50 /* copy as far as end of window */
51 memcpy(p, q, n);
52 p += n;
53 q += n;
54
55 /* see if more to copy at beginning of window */
56 if (q == s->end)
57 {
58 /* wrap pointers */
59 q = s->window;
60 if (s->write == s->end)
61 s->write = s->window;
62
63 /* compute bytes to copy */
64 n = (uInt)(s->write - q);
65 if (n > z->avail_out) n = z->avail_out;
66 if (n && r == Z_BUF_ERROR) r = Z_OK;
67
68 /* update counters */
69 z->avail_out -= n;
70 z->total_out += n;
71
72 /* update check information */
73 if (s->checkfn != NULL)
74 z->adler = s->check = (*s->checkfn)(s->check, q, n);
75
76 /* copy */
77 memcpy(p, q, n);
78 p += n;
79 q += n;
80 }
81
82 /* update pointers */
83 z->next_out = p;
84 s->read = q;
85
86 /* done */
87 return r;
88}
diff --git a/lib/zlib_inflate/infutil.h b/lib/zlib_inflate/infutil.h
index a15875fc5f72..eb1a9007bd86 100644
--- a/lib/zlib_inflate/infutil.h
+++ b/lib/zlib_inflate/infutil.h
@@ -11,184 +11,12 @@
11#ifndef _INFUTIL_H 11#ifndef _INFUTIL_H
12#define _INFUTIL_H 12#define _INFUTIL_H
13 13
14#include <linux/zconf.h> 14#include <linux/zlib.h>
15#include "inftrees.h"
16#include "infcodes.h"
17
18typedef enum {
19 TYPE, /* get type bits (3, including end bit) */
20 LENS, /* get lengths for stored */
21 STORED, /* processing stored block */
22 TABLE, /* get table lengths */
23 BTREE, /* get bit lengths tree for a dynamic block */
24 DTREE, /* get length, distance trees for a dynamic block */
25 CODES, /* processing fixed or dynamic block */
26 DRY, /* output remaining window bytes */
27 B_DONE, /* finished last block, done */
28 B_BAD} /* got a data error--stuck here */
29inflate_block_mode;
30
31/* inflate blocks semi-private state */
32struct inflate_blocks_state {
33
34 /* mode */
35 inflate_block_mode mode; /* current inflate_block mode */
36
37 /* mode dependent information */
38 union {
39 uInt left; /* if STORED, bytes left to copy */
40 struct {
41 uInt table; /* table lengths (14 bits) */
42 uInt index; /* index into blens (or border) */
43 uInt *blens; /* bit lengths of codes */
44 uInt bb; /* bit length tree depth */
45 inflate_huft *tb; /* bit length decoding tree */
46 } trees; /* if DTREE, decoding info for trees */
47 struct {
48 inflate_codes_statef
49 *codes;
50 } decode; /* if CODES, current state */
51 } sub; /* submode */
52 uInt last; /* true if this block is the last block */
53
54 /* mode independent information */
55 uInt bitk; /* bits in bit buffer */
56 uLong bitb; /* bit buffer */
57 inflate_huft *hufts; /* single malloc for tree space */
58 Byte *window; /* sliding window */
59 Byte *end; /* one byte after sliding window */
60 Byte *read; /* window read pointer */
61 Byte *write; /* window write pointer */
62 check_func checkfn; /* check function */
63 uLong check; /* check on output */
64
65};
66
67
68/* defines for inflate input/output */
69/* update pointers and return */
70#define UPDBITS {s->bitb=b;s->bitk=k;}
71#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
72#define UPDOUT {s->write=q;}
73#define UPDATE {UPDBITS UPDIN UPDOUT}
74#define LEAVE {UPDATE return zlib_inflate_flush(s,z,r);}
75/* get bytes and bits */
76#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
77#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
78#define NEXTBYTE (n--,*p++)
79#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
80#define DUMPBITS(j) {b>>=(j);k-=(j);}
81/* output bytes */
82#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
83#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
84#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
85#define FLUSH {UPDOUT r=zlib_inflate_flush(s,z,r); LOADOUT}
86#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
87#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
88/* load local pointers */
89#define LOAD {LOADIN LOADOUT}
90
91/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
92extern uInt zlib_inflate_mask[17];
93
94/* copy as much as possible from the sliding window to the output area */
95extern int zlib_inflate_flush (
96 inflate_blocks_statef *,
97 z_streamp ,
98 int);
99
100/* inflate private state */
101typedef enum {
102 METHOD, /* waiting for method byte */
103 FLAG, /* waiting for flag byte */
104 DICT4, /* four dictionary check bytes to go */
105 DICT3, /* three dictionary check bytes to go */
106 DICT2, /* two dictionary check bytes to go */
107 DICT1, /* one dictionary check byte to go */
108 DICT0, /* waiting for inflateSetDictionary */
109 BLOCKS, /* decompressing blocks */
110 CHECK4, /* four check bytes to go */
111 CHECK3, /* three check bytes to go */
112 CHECK2, /* two check bytes to go */
113 CHECK1, /* one check byte to go */
114 I_DONE, /* finished check, done */
115 I_BAD} /* got an error--stay here */
116inflate_mode;
117
118struct internal_state {
119
120 /* mode */
121 inflate_mode mode; /* current inflate mode */
122
123 /* mode dependent information */
124 union {
125 uInt method; /* if FLAGS, method byte */
126 struct {
127 uLong was; /* computed check value */
128 uLong need; /* stream check value */
129 } check; /* if CHECK, check values to compare */
130 uInt marker; /* if BAD, inflateSync's marker bytes count */
131 } sub; /* submode */
132
133 /* mode independent information */
134 int nowrap; /* flag for no wrapper */
135 uInt wbits; /* log2(window size) (8..15, defaults to 15) */
136 inflate_blocks_statef
137 *blocks; /* current inflate_blocks state */
138
139};
140
141/* inflate codes private state */
142typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
143 START, /* x: set up for LEN */
144 LEN, /* i: get length/literal/eob next */
145 LENEXT, /* i: getting length extra (have base) */
146 DIST, /* i: get distance next */
147 DISTEXT, /* i: getting distance extra */
148 COPY, /* o: copying bytes in window, waiting for space */
149 LIT, /* o: got literal, waiting for output space */
150 WASH, /* o: got eob, possibly still output waiting */
151 END, /* x: got eob and all data flushed */
152 BADCODE} /* x: got error */
153inflate_codes_mode;
154
155struct inflate_codes_state {
156
157 /* mode */
158 inflate_codes_mode mode; /* current inflate_codes mode */
159
160 /* mode dependent information */
161 uInt len;
162 union {
163 struct {
164 inflate_huft *tree; /* pointer into tree */
165 uInt need; /* bits needed */
166 } code; /* if LEN or DIST, where in tree */
167 uInt lit; /* if LIT, literal */
168 struct {
169 uInt get; /* bits to get for extra */
170 uInt dist; /* distance back to copy from */
171 } copy; /* if EXT or COPY, where and how much */
172 } sub; /* submode */
173
174 /* mode independent information */
175 Byte lbits; /* ltree bits decoded per branch */
176 Byte dbits; /* dtree bits decoder per branch */
177 inflate_huft *ltree; /* literal/length/eob tree */
178 inflate_huft *dtree; /* distance tree */
179
180};
181 15
182/* memory allocation for inflation */ 16/* memory allocation for inflation */
183 17
184struct inflate_workspace { 18struct inflate_workspace {
185 inflate_codes_statef working_state; 19 struct inflate_state inflate_state;
186 struct inflate_blocks_state working_blocks_state;
187 struct internal_state internal_state;
188 unsigned int tree_work_area_1[19];
189 unsigned int tree_work_area_2[288];
190 unsigned working_blens[258 + 0x1f + 0x1f];
191 inflate_huft working_hufts[MANY];
192 unsigned char working_window[1 << MAX_WBITS]; 20 unsigned char working_window[1 << MAX_WBITS];
193}; 21};
194 22
diff --git a/security/dummy.c b/security/dummy.c
index 64f6da0f422e..6de4a4a5eb13 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -860,7 +860,7 @@ static int dummy_setprocattr(struct task_struct *p, char *name, void *value, siz
860} 860}
861 861
862#ifdef CONFIG_KEYS 862#ifdef CONFIG_KEYS
863static inline int dummy_key_alloc(struct key *key) 863static inline int dummy_key_alloc(struct key *key, struct task_struct *ctx)
864{ 864{
865 return 0; 865 return 0;
866} 866}
diff --git a/security/keys/key.c b/security/keys/key.c
index 3fdc49c6a02c..51f851557389 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -247,8 +247,8 @@ static inline void key_alloc_serial(struct key *key)
247 * instantiate the key or discard it before returning 247 * instantiate the key or discard it before returning
248 */ 248 */
249struct key *key_alloc(struct key_type *type, const char *desc, 249struct key *key_alloc(struct key_type *type, const char *desc,
250 uid_t uid, gid_t gid, key_perm_t perm, 250 uid_t uid, gid_t gid, struct task_struct *ctx,
251 int not_in_quota) 251 key_perm_t perm, int not_in_quota)
252{ 252{
253 struct key_user *user = NULL; 253 struct key_user *user = NULL;
254 struct key *key; 254 struct key *key;
@@ -318,7 +318,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
318#endif 318#endif
319 319
320 /* let the security module know about the key */ 320 /* let the security module know about the key */
321 ret = security_key_alloc(key); 321 ret = security_key_alloc(key, ctx);
322 if (ret < 0) 322 if (ret < 0)
323 goto security_error; 323 goto security_error;
324 324
@@ -822,7 +822,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
822 822
823 /* allocate a new key */ 823 /* allocate a new key */
824 key = key_alloc(ktype, description, current->fsuid, current->fsgid, 824 key = key_alloc(ktype, description, current->fsuid, current->fsgid,
825 perm, not_in_quota); 825 current, perm, not_in_quota);
826 if (IS_ERR(key)) { 826 if (IS_ERR(key)) {
827 key_ref = ERR_PTR(PTR_ERR(key)); 827 key_ref = ERR_PTR(PTR_ERR(key));
828 goto error_3; 828 goto error_3;
@@ -907,6 +907,10 @@ void key_revoke(struct key *key)
907 * it */ 907 * it */
908 down_write(&key->sem); 908 down_write(&key->sem);
909 set_bit(KEY_FLAG_REVOKED, &key->flags); 909 set_bit(KEY_FLAG_REVOKED, &key->flags);
910
911 if (key->type->revoke)
912 key->type->revoke(key);
913
910 up_write(&key->sem); 914 up_write(&key->sem);
911 915
912} /* end key_revoke() */ 916} /* end key_revoke() */
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index bffa924c1f88..1357207fc9df 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -240,13 +240,14 @@ static long keyring_read(const struct key *keyring,
240 * allocate a keyring and link into the destination keyring 240 * allocate a keyring and link into the destination keyring
241 */ 241 */
242struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 242struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
243 int not_in_quota, struct key *dest) 243 struct task_struct *ctx, int not_in_quota,
244 struct key *dest)
244{ 245{
245 struct key *keyring; 246 struct key *keyring;
246 int ret; 247 int ret;
247 248
248 keyring = key_alloc(&key_type_keyring, description, 249 keyring = key_alloc(&key_type_keyring, description,
249 uid, gid, 250 uid, gid, ctx,
250 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, 251 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
251 not_in_quota); 252 not_in_quota);
252 253
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 217a0bef3c82..4d9825f9962c 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -67,7 +67,8 @@ struct key root_session_keyring = {
67/* 67/*
68 * allocate the keyrings to be associated with a UID 68 * allocate the keyrings to be associated with a UID
69 */ 69 */
70int alloc_uid_keyring(struct user_struct *user) 70int alloc_uid_keyring(struct user_struct *user,
71 struct task_struct *ctx)
71{ 72{
72 struct key *uid_keyring, *session_keyring; 73 struct key *uid_keyring, *session_keyring;
73 char buf[20]; 74 char buf[20];
@@ -76,7 +77,7 @@ int alloc_uid_keyring(struct user_struct *user)
76 /* concoct a default session keyring */ 77 /* concoct a default session keyring */
77 sprintf(buf, "_uid_ses.%u", user->uid); 78 sprintf(buf, "_uid_ses.%u", user->uid);
78 79
79 session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0, NULL); 80 session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0, NULL);
80 if (IS_ERR(session_keyring)) { 81 if (IS_ERR(session_keyring)) {
81 ret = PTR_ERR(session_keyring); 82 ret = PTR_ERR(session_keyring);
82 goto error; 83 goto error;
@@ -86,7 +87,7 @@ int alloc_uid_keyring(struct user_struct *user)
86 * keyring */ 87 * keyring */
87 sprintf(buf, "_uid.%u", user->uid); 88 sprintf(buf, "_uid.%u", user->uid);
88 89
89 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0, 90 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0,
90 session_keyring); 91 session_keyring);
91 if (IS_ERR(uid_keyring)) { 92 if (IS_ERR(uid_keyring)) {
92 key_put(session_keyring); 93 key_put(session_keyring);
@@ -143,7 +144,7 @@ int install_thread_keyring(struct task_struct *tsk)
143 144
144 sprintf(buf, "_tid.%u", tsk->pid); 145 sprintf(buf, "_tid.%u", tsk->pid);
145 146
146 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); 147 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
147 if (IS_ERR(keyring)) { 148 if (IS_ERR(keyring)) {
148 ret = PTR_ERR(keyring); 149 ret = PTR_ERR(keyring);
149 goto error; 150 goto error;
@@ -177,7 +178,7 @@ int install_process_keyring(struct task_struct *tsk)
177 if (!tsk->signal->process_keyring) { 178 if (!tsk->signal->process_keyring) {
178 sprintf(buf, "_pid.%u", tsk->tgid); 179 sprintf(buf, "_pid.%u", tsk->tgid);
179 180
180 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); 181 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
181 if (IS_ERR(keyring)) { 182 if (IS_ERR(keyring)) {
182 ret = PTR_ERR(keyring); 183 ret = PTR_ERR(keyring);
183 goto error; 184 goto error;
@@ -217,7 +218,7 @@ static int install_session_keyring(struct task_struct *tsk,
217 if (!keyring) { 218 if (!keyring) {
218 sprintf(buf, "_ses.%u", tsk->tgid); 219 sprintf(buf, "_ses.%u", tsk->tgid);
219 220
220 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); 221 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
221 if (IS_ERR(keyring)) 222 if (IS_ERR(keyring))
222 return PTR_ERR(keyring); 223 return PTR_ERR(keyring);
223 } 224 }
@@ -390,6 +391,8 @@ key_ref_t search_process_keyrings(struct key_type *type,
390 struct request_key_auth *rka; 391 struct request_key_auth *rka;
391 key_ref_t key_ref, ret, err; 392 key_ref_t key_ref, ret, err;
392 393
394 might_sleep();
395
393 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 396 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
394 * searchable, but we failed to find a key or we found a negative key; 397 * searchable, but we failed to find a key or we found a negative key;
395 * otherwise we want to return a sample error (probably -EACCES) if 398 * otherwise we want to return a sample error (probably -EACCES) if
@@ -495,27 +498,35 @@ key_ref_t search_process_keyrings(struct key_type *type,
495 */ 498 */
496 if (context->request_key_auth && 499 if (context->request_key_auth &&
497 context == current && 500 context == current &&
498 type != &key_type_request_key_auth && 501 type != &key_type_request_key_auth
499 key_validate(context->request_key_auth) == 0
500 ) { 502 ) {
501 rka = context->request_key_auth->payload.data; 503 /* defend against the auth key being revoked */
504 down_read(&context->request_key_auth->sem);
502 505
503 key_ref = search_process_keyrings(type, description, match, 506 if (key_validate(context->request_key_auth) == 0) {
504 rka->context); 507 rka = context->request_key_auth->payload.data;
505 508
506 if (!IS_ERR(key_ref)) 509 key_ref = search_process_keyrings(type, description,
507 goto found; 510 match, rka->context);
508 511
509 switch (PTR_ERR(key_ref)) { 512 up_read(&context->request_key_auth->sem);
510 case -EAGAIN: /* no key */ 513
511 if (ret) 514 if (!IS_ERR(key_ref))
515 goto found;
516
517 switch (PTR_ERR(key_ref)) {
518 case -EAGAIN: /* no key */
519 if (ret)
520 break;
521 case -ENOKEY: /* negative key */
522 ret = key_ref;
512 break; 523 break;
513 case -ENOKEY: /* negative key */ 524 default:
514 ret = key_ref; 525 err = key_ref;
515 break; 526 break;
516 default: 527 }
517 err = key_ref; 528 } else {
518 break; 529 up_read(&context->request_key_auth->sem);
519 } 530 }
520 } 531 }
521 532
@@ -717,7 +728,7 @@ long join_session_keyring(const char *name)
717 keyring = find_keyring_by_name(name, 0); 728 keyring = find_keyring_by_name(name, 0);
718 if (PTR_ERR(keyring) == -ENOKEY) { 729 if (PTR_ERR(keyring) == -ENOKEY) {
719 /* not found - try and create a new one */ 730 /* not found - try and create a new one */
720 keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL); 731 keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk, 0, NULL);
721 if (IS_ERR(keyring)) { 732 if (IS_ERR(keyring)) {
722 ret = PTR_ERR(keyring); 733 ret = PTR_ERR(keyring);
723 goto error2; 734 goto error2;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index f030a0ccbb93..eab66a06ca53 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -48,7 +48,8 @@ static int call_sbin_request_key(struct key *key,
48 /* allocate a new session keyring */ 48 /* allocate a new session keyring */
49 sprintf(desc, "_req.%u", key->serial); 49 sprintf(desc, "_req.%u", key->serial);
50 50
51 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL); 51 keyring = keyring_alloc(desc, current->fsuid, current->fsgid,
52 current, 1, NULL);
52 if (IS_ERR(keyring)) { 53 if (IS_ERR(keyring)) {
53 ret = PTR_ERR(keyring); 54 ret = PTR_ERR(keyring);
54 goto error_alloc; 55 goto error_alloc;
@@ -137,7 +138,8 @@ static struct key *__request_key_construction(struct key_type *type,
137 138
138 /* create a key and add it to the queue */ 139 /* create a key and add it to the queue */
139 key = key_alloc(type, description, 140 key = key_alloc(type, description,
140 current->fsuid, current->fsgid, KEY_POS_ALL, 0); 141 current->fsuid, current->fsgid,
142 current, KEY_POS_ALL, 0);
141 if (IS_ERR(key)) 143 if (IS_ERR(key))
142 goto alloc_failed; 144 goto alloc_failed;
143 145
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index cce6ba6b0323..cb9817ced3fd 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -20,6 +20,7 @@
20 20
21static int request_key_auth_instantiate(struct key *, const void *, size_t); 21static int request_key_auth_instantiate(struct key *, const void *, size_t);
22static void request_key_auth_describe(const struct key *, struct seq_file *); 22static void request_key_auth_describe(const struct key *, struct seq_file *);
23static void request_key_auth_revoke(struct key *);
23static void request_key_auth_destroy(struct key *); 24static void request_key_auth_destroy(struct key *);
24static long request_key_auth_read(const struct key *, char __user *, size_t); 25static long request_key_auth_read(const struct key *, char __user *, size_t);
25 26
@@ -31,6 +32,7 @@ struct key_type key_type_request_key_auth = {
31 .def_datalen = sizeof(struct request_key_auth), 32 .def_datalen = sizeof(struct request_key_auth),
32 .instantiate = request_key_auth_instantiate, 33 .instantiate = request_key_auth_instantiate,
33 .describe = request_key_auth_describe, 34 .describe = request_key_auth_describe,
35 .revoke = request_key_auth_revoke,
34 .destroy = request_key_auth_destroy, 36 .destroy = request_key_auth_destroy,
35 .read = request_key_auth_read, 37 .read = request_key_auth_read,
36}; 38};
@@ -93,6 +95,24 @@ static long request_key_auth_read(const struct key *key,
93 95
94/*****************************************************************************/ 96/*****************************************************************************/
95/* 97/*
98 * handle revocation of an authorisation token key
99 * - called with the key sem write-locked
100 */
101static void request_key_auth_revoke(struct key *key)
102{
103 struct request_key_auth *rka = key->payload.data;
104
105 kenter("{%d}", key->serial);
106
107 if (rka->context) {
108 put_task_struct(rka->context);
109 rka->context = NULL;
110 }
111
112} /* end request_key_auth_revoke() */
113
114/*****************************************************************************/
115/*
96 * destroy an instantiation authorisation token key 116 * destroy an instantiation authorisation token key
97 */ 117 */
98static void request_key_auth_destroy(struct key *key) 118static void request_key_auth_destroy(struct key *key)
@@ -101,6 +121,11 @@ static void request_key_auth_destroy(struct key *key)
101 121
102 kenter("{%d}", key->serial); 122 kenter("{%d}", key->serial);
103 123
124 if (rka->context) {
125 put_task_struct(rka->context);
126 rka->context = NULL;
127 }
128
104 key_put(rka->target_key); 129 key_put(rka->target_key);
105 kfree(rka); 130 kfree(rka);
106 131
@@ -131,14 +156,26 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
131 * another process */ 156 * another process */
132 if (current->request_key_auth) { 157 if (current->request_key_auth) {
133 /* it is - use that instantiation context here too */ 158 /* it is - use that instantiation context here too */
159 down_read(&current->request_key_auth->sem);
160
161 /* if the auth key has been revoked, then the key we're
162 * servicing is already instantiated */
163 if (test_bit(KEY_FLAG_REVOKED,
164 &current->request_key_auth->flags))
165 goto auth_key_revoked;
166
134 irka = current->request_key_auth->payload.data; 167 irka = current->request_key_auth->payload.data;
135 rka->context = irka->context; 168 rka->context = irka->context;
136 rka->pid = irka->pid; 169 rka->pid = irka->pid;
170 get_task_struct(rka->context);
171
172 up_read(&current->request_key_auth->sem);
137 } 173 }
138 else { 174 else {
139 /* it isn't - use this process as the context */ 175 /* it isn't - use this process as the context */
140 rka->context = current; 176 rka->context = current;
141 rka->pid = current->pid; 177 rka->pid = current->pid;
178 get_task_struct(rka->context);
142 } 179 }
143 180
144 rka->target_key = key_get(target); 181 rka->target_key = key_get(target);
@@ -148,7 +185,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
148 sprintf(desc, "%x", target->serial); 185 sprintf(desc, "%x", target->serial);
149 186
150 authkey = key_alloc(&key_type_request_key_auth, desc, 187 authkey = key_alloc(&key_type_request_key_auth, desc,
151 current->fsuid, current->fsgid, 188 current->fsuid, current->fsgid, current,
152 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | 189 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
153 KEY_USR_VIEW, 1); 190 KEY_USR_VIEW, 1);
154 if (IS_ERR(authkey)) { 191 if (IS_ERR(authkey)) {
@@ -161,9 +198,15 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
161 if (ret < 0) 198 if (ret < 0)
162 goto error_inst; 199 goto error_inst;
163 200
164 kleave(" = {%d})", authkey->serial); 201 kleave(" = {%d}", authkey->serial);
165 return authkey; 202 return authkey;
166 203
204auth_key_revoked:
205 up_read(&current->request_key_auth->sem);
206 kfree(rka);
207 kleave("= -EKEYREVOKED");
208 return ERR_PTR(-EKEYREVOKED);
209
167error_inst: 210error_inst:
168 key_revoke(authkey); 211 key_revoke(authkey);
169 key_put(authkey); 212 key_put(authkey);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 54adc9d31e92..524915dfda64 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4252,6 +4252,57 @@ static int selinux_setprocattr(struct task_struct *p,
4252 return size; 4252 return size;
4253} 4253}
4254 4254
4255#ifdef CONFIG_KEYS
4256
4257static int selinux_key_alloc(struct key *k, struct task_struct *tsk)
4258{
4259 struct task_security_struct *tsec = tsk->security;
4260 struct key_security_struct *ksec;
4261
4262 ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
4263 if (!ksec)
4264 return -ENOMEM;
4265
4266 ksec->obj = k;
4267 ksec->sid = tsec->sid;
4268 k->security = ksec;
4269
4270 return 0;
4271}
4272
4273static void selinux_key_free(struct key *k)
4274{
4275 struct key_security_struct *ksec = k->security;
4276
4277 k->security = NULL;
4278 kfree(ksec);
4279}
4280
4281static int selinux_key_permission(key_ref_t key_ref,
4282 struct task_struct *ctx,
4283 key_perm_t perm)
4284{
4285 struct key *key;
4286 struct task_security_struct *tsec;
4287 struct key_security_struct *ksec;
4288
4289 key = key_ref_to_ptr(key_ref);
4290
4291 tsec = ctx->security;
4292 ksec = key->security;
4293
4294 /* if no specific permissions are requested, we skip the
4295 permission check. No serious, additional covert channels
4296 appear to be created. */
4297 if (perm == 0)
4298 return 0;
4299
4300 return avc_has_perm(tsec->sid, ksec->sid,
4301 SECCLASS_KEY, perm, NULL);
4302}
4303
4304#endif
4305
4255static struct security_operations selinux_ops = { 4306static struct security_operations selinux_ops = {
4256 .ptrace = selinux_ptrace, 4307 .ptrace = selinux_ptrace,
4257 .capget = selinux_capget, 4308 .capget = selinux_capget,
@@ -4406,6 +4457,12 @@ static struct security_operations selinux_ops = {
4406 .xfrm_state_delete_security = selinux_xfrm_state_delete, 4457 .xfrm_state_delete_security = selinux_xfrm_state_delete,
4407 .xfrm_policy_lookup = selinux_xfrm_policy_lookup, 4458 .xfrm_policy_lookup = selinux_xfrm_policy_lookup,
4408#endif 4459#endif
4460
4461#ifdef CONFIG_KEYS
4462 .key_alloc = selinux_key_alloc,
4463 .key_free = selinux_key_free,
4464 .key_permission = selinux_key_permission,
4465#endif
4409}; 4466};
4410 4467
4411static __init int selinux_init(void) 4468static __init int selinux_init(void)
@@ -4441,6 +4498,13 @@ static __init int selinux_init(void)
4441 } else { 4498 } else {
4442 printk(KERN_INFO "SELinux: Starting in permissive mode\n"); 4499 printk(KERN_INFO "SELinux: Starting in permissive mode\n");
4443 } 4500 }
4501
4502#ifdef CONFIG_KEYS
4503 /* Add security information to initial keyrings */
4504 security_key_alloc(&root_user_keyring, current);
4505 security_key_alloc(&root_session_keyring, current);
4506#endif
4507
4444 return 0; 4508 return 0;
4445} 4509}
4446 4510
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
index 70ee65a58817..bc020bde6c86 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -242,3 +242,9 @@
242 S_(SECCLASS_PACKET, PACKET__SEND, "send") 242 S_(SECCLASS_PACKET, PACKET__SEND, "send")
243 S_(SECCLASS_PACKET, PACKET__RECV, "recv") 243 S_(SECCLASS_PACKET, PACKET__RECV, "recv")
244 S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto") 244 S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto")
245 S_(SECCLASS_KEY, KEY__VIEW, "view")
246 S_(SECCLASS_KEY, KEY__READ, "read")
247 S_(SECCLASS_KEY, KEY__WRITE, "write")
248 S_(SECCLASS_KEY, KEY__SEARCH, "search")
249 S_(SECCLASS_KEY, KEY__LINK, "link")
250 S_(SECCLASS_KEY, KEY__SETATTR, "setattr")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index 1d9cf3d306bc..1205227a3a33 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -959,3 +959,11 @@
959#define PACKET__SEND 0x00000001UL 959#define PACKET__SEND 0x00000001UL
960#define PACKET__RECV 0x00000002UL 960#define PACKET__RECV 0x00000002UL
961#define PACKET__RELABELTO 0x00000004UL 961#define PACKET__RELABELTO 0x00000004UL
962
963#define KEY__VIEW 0x00000001UL
964#define KEY__READ 0x00000002UL
965#define KEY__WRITE 0x00000004UL
966#define KEY__SEARCH 0x00000008UL
967#define KEY__LINK 0x00000010UL
968#define KEY__SETATTR 0x00000020UL
969
diff --git a/security/selinux/include/class_to_string.h b/security/selinux/include/class_to_string.h
index 3aec75fee4f7..24303b61309f 100644
--- a/security/selinux/include/class_to_string.h
+++ b/security/selinux/include/class_to_string.h
@@ -60,3 +60,4 @@
60 S_("netlink_kobject_uevent_socket") 60 S_("netlink_kobject_uevent_socket")
61 S_("appletalk_socket") 61 S_("appletalk_socket")
62 S_("packet") 62 S_("packet")
63 S_("key")
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h
index a0eb9e281d18..95887aed2a68 100644
--- a/security/selinux/include/flask.h
+++ b/security/selinux/include/flask.h
@@ -62,6 +62,7 @@
62#define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 55 62#define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 55
63#define SECCLASS_APPLETALK_SOCKET 56 63#define SECCLASS_APPLETALK_SOCKET 56
64#define SECCLASS_PACKET 57 64#define SECCLASS_PACKET 57
65#define SECCLASS_KEY 58
65 66
66/* 67/*
67 * Security identifier indices for initial entities 68 * Security identifier indices for initial entities
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 54c030778882..8f5547ad1856 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -99,6 +99,11 @@ struct sk_security_struct {
99 u32 peer_sid; /* SID of peer */ 99 u32 peer_sid; /* SID of peer */
100}; 100};
101 101
102struct key_security_struct {
103 struct key *obj; /* back pointer */
104 u32 sid; /* SID of key */
105};
106
102extern unsigned int selinux_checkreqprot; 107extern unsigned int selinux_checkreqprot;
103 108
104#endif /* _SELINUX_OBJSEC_H_ */ 109#endif /* _SELINUX_OBJSEC_H_ */
diff --git a/sound/Kconfig b/sound/Kconfig
index b65ee4701f98..e0d791a98452 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -58,6 +58,8 @@ source "sound/pci/Kconfig"
58 58
59source "sound/ppc/Kconfig" 59source "sound/ppc/Kconfig"
60 60
61source "sound/aoa/Kconfig"
62
61source "sound/arm/Kconfig" 63source "sound/arm/Kconfig"
62 64
63source "sound/mips/Kconfig" 65source "sound/mips/Kconfig"
diff --git a/sound/Makefile b/sound/Makefile
index f352bb235968..a682ea30f0c9 100644
--- a/sound/Makefile
+++ b/sound/Makefile
@@ -4,7 +4,7 @@
4obj-$(CONFIG_SOUND) += soundcore.o 4obj-$(CONFIG_SOUND) += soundcore.o
5obj-$(CONFIG_SOUND_PRIME) += oss/ 5obj-$(CONFIG_SOUND_PRIME) += oss/
6obj-$(CONFIG_DMASOUND) += oss/ 6obj-$(CONFIG_DMASOUND) += oss/
7obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ 7obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ aoa/
8 8
9ifeq ($(CONFIG_SND),y) 9ifeq ($(CONFIG_SND),y)
10 obj-y += last.o 10 obj-y += last.o
diff --git a/sound/aoa/Kconfig b/sound/aoa/Kconfig
new file mode 100644
index 000000000000..a85194fe0b06
--- /dev/null
+++ b/sound/aoa/Kconfig
@@ -0,0 +1,17 @@
1menu "Apple Onboard Audio driver"
2 depends on SND!=n && PPC
3
4config SND_AOA
5 tristate "Apple Onboard Audio driver"
6 depends on SOUND && SND_PCM
7 ---help---
8 This option enables the new driver for the various
9 Apple Onboard Audio components.
10
11source "sound/aoa/fabrics/Kconfig"
12
13source "sound/aoa/codecs/Kconfig"
14
15source "sound/aoa/soundbus/Kconfig"
16
17endmenu
diff --git a/sound/aoa/Makefile b/sound/aoa/Makefile
new file mode 100644
index 000000000000..d8de3e7df48d
--- /dev/null
+++ b/sound/aoa/Makefile
@@ -0,0 +1,4 @@
1obj-$(CONFIG_SND_AOA) += core/
2obj-$(CONFIG_SND_AOA) += codecs/
3obj-$(CONFIG_SND_AOA) += fabrics/
4obj-$(CONFIG_SND_AOA_SOUNDBUS) += soundbus/
diff --git a/sound/aoa/aoa-gpio.h b/sound/aoa/aoa-gpio.h
new file mode 100644
index 000000000000..3a61f3115573
--- /dev/null
+++ b/sound/aoa/aoa-gpio.h
@@ -0,0 +1,81 @@
1/*
2 * Apple Onboard Audio GPIO definitions
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#ifndef __AOA_GPIO_H
10#define __AOA_GPIO_H
11#include <linux/workqueue.h>
12#include <linux/mutex.h>
13#include <asm/prom.h>
14
15typedef void (*notify_func_t)(void *data);
16
17enum notify_type {
18 AOA_NOTIFY_HEADPHONE,
19 AOA_NOTIFY_LINE_IN,
20 AOA_NOTIFY_LINE_OUT,
21};
22
23struct gpio_runtime;
24struct gpio_methods {
25 /* for initialisation/de-initialisation of the GPIO layer */
26 void (*init)(struct gpio_runtime *rt);
27 void (*exit)(struct gpio_runtime *rt);
28
29 /* turn off headphone, speakers, lineout */
30 void (*all_amps_off)(struct gpio_runtime *rt);
31 /* turn headphone, speakers, lineout back to previous setting */
32 void (*all_amps_restore)(struct gpio_runtime *rt);
33
34 void (*set_headphone)(struct gpio_runtime *rt, int on);
35 void (*set_speakers)(struct gpio_runtime *rt, int on);
36 void (*set_lineout)(struct gpio_runtime *rt, int on);
37
38 int (*get_headphone)(struct gpio_runtime *rt);
39 int (*get_speakers)(struct gpio_runtime *rt);
40 int (*get_lineout)(struct gpio_runtime *rt);
41
42 void (*set_hw_reset)(struct gpio_runtime *rt, int on);
43
44 /* use this to be notified of any events. The notification
45 * function is passed the data, and is called in process
46 * context by the use of schedule_work.
47 * The interface for it is that setting a function to NULL
48 * removes it, and they return 0 if the operation succeeded,
49 * and -EBUSY if the notification is already assigned by
50 * someone else. */
51 int (*set_notify)(struct gpio_runtime *rt,
52 enum notify_type type,
53 notify_func_t notify,
54 void *data);
55 /* returns 0 if not plugged in, 1 if plugged in
56 * or a negative error code */
57 int (*get_detect)(struct gpio_runtime *rt,
58 enum notify_type type);
59};
60
61struct gpio_notification {
62 notify_func_t notify;
63 void *data;
64 void *gpio_private;
65 struct work_struct work;
66 struct mutex mutex;
67};
68
69struct gpio_runtime {
70 /* to be assigned by fabric */
71 struct device_node *node;
72 /* since everyone needs this pointer anyway... */
73 struct gpio_methods *methods;
74 /* to be used by the gpio implementation */
75 int implementation_private;
76 struct gpio_notification headphone_notify;
77 struct gpio_notification line_in_notify;
78 struct gpio_notification line_out_notify;
79};
80
81#endif /* __AOA_GPIO_H */
diff --git a/sound/aoa/aoa.h b/sound/aoa/aoa.h
new file mode 100644
index 000000000000..378ef1e9879b
--- /dev/null
+++ b/sound/aoa/aoa.h
@@ -0,0 +1,131 @@
1/*
2 * Apple Onboard Audio definitions
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#ifndef __AOA_H
10#define __AOA_H
11#include <asm/prom.h>
12#include <linux/module.h>
13/* So apparently there's a reason for requiring driver.h to be included first! */
14#include <sound/driver.h>
15#include <sound/core.h>
16#include <sound/asound.h>
17#include <sound/control.h>
18#include "aoa-gpio.h"
19#include "soundbus/soundbus.h"
20
21#define MAX_CODEC_NAME_LEN 32
22
23struct aoa_codec {
24 char name[MAX_CODEC_NAME_LEN];
25
26 struct module *owner;
27
28 /* called when the fabric wants to init this codec.
29 * Do alsa card manipulations from here. */
30 int (*init)(struct aoa_codec *codec);
31
32 /* called when the fabric is done with the codec.
33 * The alsa card will be cleaned up so don't bother. */
34 void (*exit)(struct aoa_codec *codec);
35
36 /* May be NULL, but can be used by the fabric.
37 * Refcounting is the codec driver's responsibility */
38 struct device_node *node;
39
40 /* assigned by fabric before init() is called, points
41 * to the soundbus device. Cannot be NULL. */
42 struct soundbus_dev *soundbus_dev;
43
44 /* assigned by the fabric before init() is called, points
45 * to the fabric's gpio runtime record for the relevant
46 * device. */
47 struct gpio_runtime *gpio;
48
49 /* assigned by the fabric before init() is called, contains
50 * a codec specific bitmask of what outputs and inputs are
51 * actually connected */
52 u32 connected;
53
54 /* data the fabric can associate with this structure */
55 void *fabric_data;
56
57 /* private! */
58 struct list_head list;
59 struct aoa_fabric *fabric;
60};
61
62/* return 0 on success */
63extern int
64aoa_codec_register(struct aoa_codec *codec);
65extern void
66aoa_codec_unregister(struct aoa_codec *codec);
67
68#define MAX_LAYOUT_NAME_LEN 32
69
70struct aoa_fabric {
71 char name[MAX_LAYOUT_NAME_LEN];
72
73 struct module *owner;
74
75 /* once codecs register, they are passed here after.
76 * They are of course not initialised, since the
77 * fabric is responsible for initialising some fields
78 * in the codec structure! */
79 int (*found_codec)(struct aoa_codec *codec);
80 /* called for each codec when it is removed,
81 * also in the case that aoa_fabric_unregister
82 * is called and all codecs are removed
83 * from this fabric.
84 * Also called if found_codec returned 0 but
85 * the codec couldn't initialise. */
86 void (*remove_codec)(struct aoa_codec *codec);
87 /* If found_codec returned 0, and the codec
88 * could be initialised, this is called. */
89 void (*attached_codec)(struct aoa_codec *codec);
90};
91
92/* return 0 on success, -EEXIST if another fabric is
93 * registered, -EALREADY if the same fabric is registered.
94 * Passing NULL can be used to test for the presence
95 * of another fabric, if -EALREADY is returned there is
96 * no other fabric present.
97 * In the case that the function returns -EALREADY
98 * and the fabric passed is not NULL, all codecs
99 * that are not assigned yet are passed to the fabric
100 * again for reconsideration. */
101extern int
102aoa_fabric_register(struct aoa_fabric *fabric);
103
104/* it is vital to call this when the fabric exits!
105 * When calling, the remove_codec will be called
106 * for all codecs, unless it is NULL. */
107extern void
108aoa_fabric_unregister(struct aoa_fabric *fabric);
109
110/* if for some reason you want to get rid of a codec
111 * before the fabric is removed, use this.
112 * Note that remove_codec is called for it! */
113extern void
114aoa_fabric_unlink_codec(struct aoa_codec *codec);
115
116/* alsa help methods */
117struct aoa_card {
118 struct snd_card *alsa_card;
119};
120
121extern int aoa_snd_device_new(snd_device_type_t type,
122 void * device_data, struct snd_device_ops * ops);
123extern struct snd_card *aoa_get_card(void);
124extern int aoa_snd_ctl_add(struct snd_kcontrol* control);
125
126/* GPIO stuff */
127extern struct gpio_methods *pmf_gpio_methods;
128extern struct gpio_methods *ftr_gpio_methods;
129/* extern struct gpio_methods *map_gpio_methods; */
130
131#endif /* __AOA_H */
diff --git a/sound/aoa/codecs/Kconfig b/sound/aoa/codecs/Kconfig
new file mode 100644
index 000000000000..90cf58f68630
--- /dev/null
+++ b/sound/aoa/codecs/Kconfig
@@ -0,0 +1,32 @@
1config SND_AOA_ONYX
2 tristate "support Onyx chip"
3 depends on SND_AOA
4 ---help---
5 This option enables support for the Onyx (pcm3052)
6 codec chip found in the latest Apple machines
7 (most of those with digital audio output).
8
9#config SND_AOA_TOPAZ
10# tristate "support Topaz chips"
11# depends on SND_AOA
12# ---help---
13# This option enables support for the Topaz (CS84xx)
14# codec chips found in the latest Apple machines,
15# these chips do the digital input and output on
16# some PowerMacs.
17
18config SND_AOA_TAS
19 tristate "support TAS chips"
20 depends on SND_AOA
21 ---help---
22 This option enables support for the tas chips
23 found in a lot of Apple Machines, especially
24 iBooks and PowerBooks without digital.
25
26config SND_AOA_TOONIE
27 tristate "support Toonie chip"
28 depends on SND_AOA
29 ---help---
30 This option enables support for the toonie codec
31 found in the Mac Mini. If you have a Mac Mini and
32 want to hear sound, select this option.
diff --git a/sound/aoa/codecs/Makefile b/sound/aoa/codecs/Makefile
new file mode 100644
index 000000000000..31cbe68fd42f
--- /dev/null
+++ b/sound/aoa/codecs/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_SND_AOA_ONYX) += snd-aoa-codec-onyx.o
2obj-$(CONFIG_SND_AOA_TAS) += snd-aoa-codec-tas.o
3obj-$(CONFIG_SND_AOA_TOONIE) += snd-aoa-codec-toonie.o
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/snd-aoa-codec-onyx.c
new file mode 100644
index 000000000000..0b7650788f1f
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-onyx.c
@@ -0,0 +1,1113 @@
1/*
2 * Apple Onboard Audio driver for Onyx codec
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 *
8 *
9 * This is a driver for the pcm3052 codec chip (codenamed Onyx)
10 * that is present in newer Apple hardware (with digital output).
11 *
12 * The Onyx codec has the following connections (listed by the bit
13 * to be used in aoa_codec.connected):
14 * 0: analog output
15 * 1: digital output
16 * 2: line input
17 * 3: microphone input
18 * Note that even though I know of no machine that has for example
19 * the digital output connected but not the analog, I have handled
20 * all the different cases in the code so that this driver may serve
21 * as a good example of what to do.
22 *
23 * NOTE: This driver assumes that there's at most one chip to be
24 * used with one alsa card, in form of creating all kinds
25 * of mixer elements without regard for their existence.
26 * But snd-aoa assumes that there's at most one card, so
27 * this means you can only have one onyx on a system. This
28 * should probably be fixed by changing the assumption of
29 * having just a single card on a system, and making the
30 * 'card' pointer accessible to anyone who needs it instead
31 * of hiding it in the aoa_snd_* functions...
32 *
33 */
34#include <linux/delay.h>
35#include <linux/module.h>
36MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
37MODULE_LICENSE("GPL");
38MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");
39
40#include "snd-aoa-codec-onyx.h"
41#include "../aoa.h"
42#include "../soundbus/soundbus.h"
43
44
45#define PFX "snd-aoa-codec-onyx: "
46
47struct onyx {
48 /* cache registers 65 to 80, they are write-only! */
49 u8 cache[16];
50 struct i2c_client i2c;
51 struct aoa_codec codec;
52 u32 initialised:1,
53 spdif_locked:1,
54 analog_locked:1,
55 original_mute:2;
56 int open_count;
57 struct codec_info *codec_info;
58
59 /* mutex serializes concurrent access to the device
60 * and this structure.
61 */
62 struct mutex mutex;
63};
64#define codec_to_onyx(c) container_of(c, struct onyx, codec)
65
66/* both return 0 if all ok, else on error */
67static int onyx_read_register(struct onyx *onyx, u8 reg, u8 *value)
68{
69 s32 v;
70
71 if (reg != ONYX_REG_CONTROL) {
72 *value = onyx->cache[reg-FIRSTREGISTER];
73 return 0;
74 }
75 v = i2c_smbus_read_byte_data(&onyx->i2c, reg);
76 if (v < 0)
77 return -1;
78 *value = (u8)v;
79 onyx->cache[ONYX_REG_CONTROL-FIRSTREGISTER] = *value;
80 return 0;
81}
82
83static int onyx_write_register(struct onyx *onyx, u8 reg, u8 value)
84{
85 int result;
86
87 result = i2c_smbus_write_byte_data(&onyx->i2c, reg, value);
88 if (!result)
89 onyx->cache[reg-FIRSTREGISTER] = value;
90 return result;
91}
92
93/* alsa stuff */
94
95static int onyx_dev_register(struct snd_device *dev)
96{
97 return 0;
98}
99
100static struct snd_device_ops ops = {
101 .dev_register = onyx_dev_register,
102};
103
104/* this is necessary because most alsa mixer programs
105 * can't properly handle the negative range */
106#define VOLUME_RANGE_SHIFT 128
107
108static int onyx_snd_vol_info(struct snd_kcontrol *kcontrol,
109 struct snd_ctl_elem_info *uinfo)
110{
111 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
112 uinfo->count = 2;
113 uinfo->value.integer.min = -128 + VOLUME_RANGE_SHIFT;
114 uinfo->value.integer.max = -1 + VOLUME_RANGE_SHIFT;
115 return 0;
116}
117
118static int onyx_snd_vol_get(struct snd_kcontrol *kcontrol,
119 struct snd_ctl_elem_value *ucontrol)
120{
121 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
122 s8 l, r;
123
124 mutex_lock(&onyx->mutex);
125 onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
126 onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);
127 mutex_unlock(&onyx->mutex);
128
129 ucontrol->value.integer.value[0] = l + VOLUME_RANGE_SHIFT;
130 ucontrol->value.integer.value[1] = r + VOLUME_RANGE_SHIFT;
131
132 return 0;
133}
134
135static int onyx_snd_vol_put(struct snd_kcontrol *kcontrol,
136 struct snd_ctl_elem_value *ucontrol)
137{
138 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
139 s8 l, r;
140
141 mutex_lock(&onyx->mutex);
142 onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
143 onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);
144
145 if (l + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[0] &&
146 r + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[1]) {
147 mutex_unlock(&onyx->mutex);
148 return 0;
149 }
150
151 onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_LEFT,
152 ucontrol->value.integer.value[0]
153 - VOLUME_RANGE_SHIFT);
154 onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT,
155 ucontrol->value.integer.value[1]
156 - VOLUME_RANGE_SHIFT);
157 mutex_unlock(&onyx->mutex);
158
159 return 1;
160}
161
162static struct snd_kcontrol_new volume_control = {
163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
164 .name = "Master Playback Volume",
165 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
166 .info = onyx_snd_vol_info,
167 .get = onyx_snd_vol_get,
168 .put = onyx_snd_vol_put,
169};
170
171/* like above, this is necessary because a lot
172 * of alsa mixer programs don't handle ranges
173 * that don't start at 0 properly.
174 * even alsamixer is one of them... */
175#define INPUTGAIN_RANGE_SHIFT (-3)
176
177static int onyx_snd_inputgain_info(struct snd_kcontrol *kcontrol,
178 struct snd_ctl_elem_info *uinfo)
179{
180 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
181 uinfo->count = 1;
182 uinfo->value.integer.min = 3 + INPUTGAIN_RANGE_SHIFT;
183 uinfo->value.integer.max = 28 + INPUTGAIN_RANGE_SHIFT;
184 return 0;
185}
186
187static int onyx_snd_inputgain_get(struct snd_kcontrol *kcontrol,
188 struct snd_ctl_elem_value *ucontrol)
189{
190 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
191 u8 ig;
192
193 mutex_lock(&onyx->mutex);
194 onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &ig);
195 mutex_unlock(&onyx->mutex);
196
197 ucontrol->value.integer.value[0] =
198 (ig & ONYX_ADC_PGA_GAIN_MASK) + INPUTGAIN_RANGE_SHIFT;
199
200 return 0;
201}
202
203static int onyx_snd_inputgain_put(struct snd_kcontrol *kcontrol,
204 struct snd_ctl_elem_value *ucontrol)
205{
206 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
207 u8 v, n;
208
209 mutex_lock(&onyx->mutex);
210 onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
211 n = v;
212 n &= ~ONYX_ADC_PGA_GAIN_MASK;
213 n |= (ucontrol->value.integer.value[0] - INPUTGAIN_RANGE_SHIFT)
214 & ONYX_ADC_PGA_GAIN_MASK;
215 onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, n);
216 mutex_unlock(&onyx->mutex);
217
218 return n != v;
219}
220
221static struct snd_kcontrol_new inputgain_control = {
222 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
223 .name = "Master Capture Volume",
224 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
225 .info = onyx_snd_inputgain_info,
226 .get = onyx_snd_inputgain_get,
227 .put = onyx_snd_inputgain_put,
228};
229
230static int onyx_snd_capture_source_info(struct snd_kcontrol *kcontrol,
231 struct snd_ctl_elem_info *uinfo)
232{
233 static char *texts[] = { "Line-In", "Microphone" };
234
235 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
236 uinfo->count = 1;
237 uinfo->value.enumerated.items = 2;
238 if (uinfo->value.enumerated.item > 1)
239 uinfo->value.enumerated.item = 1;
240 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
241 return 0;
242}
243
244static int onyx_snd_capture_source_get(struct snd_kcontrol *kcontrol,
245 struct snd_ctl_elem_value *ucontrol)
246{
247 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
248 s8 v;
249
250 mutex_lock(&onyx->mutex);
251 onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
252 mutex_unlock(&onyx->mutex);
253
254 ucontrol->value.enumerated.item[0] = !!(v&ONYX_ADC_INPUT_MIC);
255
256 return 0;
257}
258
259static void onyx_set_capture_source(struct onyx *onyx, int mic)
260{
261 s8 v;
262
263 mutex_lock(&onyx->mutex);
264 onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
265 v &= ~ONYX_ADC_INPUT_MIC;
266 if (mic)
267 v |= ONYX_ADC_INPUT_MIC;
268 onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, v);
269 mutex_unlock(&onyx->mutex);
270}
271
272static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol,
273 struct snd_ctl_elem_value *ucontrol)
274{
275 onyx_set_capture_source(snd_kcontrol_chip(kcontrol),
276 ucontrol->value.enumerated.item[0]);
277 return 1;
278}
279
280static struct snd_kcontrol_new capture_source_control = {
281 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
282 /* If we name this 'Input Source', it properly shows up in
283 * alsamixer as a selection, * but it's shown under the
284 * 'Playback' category.
285 * If I name it 'Capture Source', it shows up in strange
286 * ways (two bools of which one can be selected at a
287 * time) but at least it's shown in the 'Capture'
288 * category.
289 * I was told that this was due to backward compatibility,
290 * but I don't understand then why the mangling is *not*
291 * done when I name it "Input Source".....
292 */
293 .name = "Capture Source",
294 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
295 .info = onyx_snd_capture_source_info,
296 .get = onyx_snd_capture_source_get,
297 .put = onyx_snd_capture_source_put,
298};
299
300static int onyx_snd_mute_info(struct snd_kcontrol *kcontrol,
301 struct snd_ctl_elem_info *uinfo)
302{
303 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
304 uinfo->count = 2;
305 uinfo->value.integer.min = 0;
306 uinfo->value.integer.max = 1;
307 return 0;
308}
309
310static int onyx_snd_mute_get(struct snd_kcontrol *kcontrol,
311 struct snd_ctl_elem_value *ucontrol)
312{
313 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
314 u8 c;
315
316 mutex_lock(&onyx->mutex);
317 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &c);
318 mutex_unlock(&onyx->mutex);
319
320 ucontrol->value.integer.value[0] = !(c & ONYX_MUTE_LEFT);
321 ucontrol->value.integer.value[1] = !(c & ONYX_MUTE_RIGHT);
322
323 return 0;
324}
325
326static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol,
327 struct snd_ctl_elem_value *ucontrol)
328{
329 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
330 u8 v = 0, c = 0;
331 int err = -EBUSY;
332
333 mutex_lock(&onyx->mutex);
334 if (onyx->analog_locked)
335 goto out_unlock;
336
337 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
338 c = v;
339 c &= ~(ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT);
340 if (!ucontrol->value.integer.value[0])
341 c |= ONYX_MUTE_LEFT;
342 if (!ucontrol->value.integer.value[1])
343 c |= ONYX_MUTE_RIGHT;
344 err = onyx_write_register(onyx, ONYX_REG_DAC_CONTROL, c);
345
346 out_unlock:
347 mutex_unlock(&onyx->mutex);
348
349 return !err ? (v != c) : err;
350}
351
352static struct snd_kcontrol_new mute_control = {
353 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
354 .name = "Master Playback Switch",
355 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
356 .info = onyx_snd_mute_info,
357 .get = onyx_snd_mute_get,
358 .put = onyx_snd_mute_put,
359};
360
361
362static int onyx_snd_single_bit_info(struct snd_kcontrol *kcontrol,
363 struct snd_ctl_elem_info *uinfo)
364{
365 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
366 uinfo->count = 1;
367 uinfo->value.integer.min = 0;
368 uinfo->value.integer.max = 1;
369 return 0;
370}
371
372#define FLAG_POLARITY_INVERT 1
373#define FLAG_SPDIFLOCK 2
374
375static int onyx_snd_single_bit_get(struct snd_kcontrol *kcontrol,
376 struct snd_ctl_elem_value *ucontrol)
377{
378 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
379 u8 c;
380 long int pv = kcontrol->private_value;
381 u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
382 u8 address = (pv >> 8) & 0xff;
383 u8 mask = pv & 0xff;
384
385 mutex_lock(&onyx->mutex);
386 onyx_read_register(onyx, address, &c);
387 mutex_unlock(&onyx->mutex);
388
389 ucontrol->value.integer.value[0] = !!(c & mask) ^ polarity;
390
391 return 0;
392}
393
394static int onyx_snd_single_bit_put(struct snd_kcontrol *kcontrol,
395 struct snd_ctl_elem_value *ucontrol)
396{
397 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
398 u8 v = 0, c = 0;
399 int err;
400 long int pv = kcontrol->private_value;
401 u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
402 u8 spdiflock = (pv >> 16) & FLAG_SPDIFLOCK;
403 u8 address = (pv >> 8) & 0xff;
404 u8 mask = pv & 0xff;
405
406 mutex_lock(&onyx->mutex);
407 if (spdiflock && onyx->spdif_locked) {
408 /* even if alsamixer doesn't care.. */
409 err = -EBUSY;
410 goto out_unlock;
411 }
412 onyx_read_register(onyx, address, &v);
413 c = v;
414 c &= ~(mask);
415 if (!!ucontrol->value.integer.value[0] ^ polarity)
416 c |= mask;
417 err = onyx_write_register(onyx, address, c);
418
419 out_unlock:
420 mutex_unlock(&onyx->mutex);
421
422 return !err ? (v != c) : err;
423}
424
425#define SINGLE_BIT(n, type, description, address, mask, flags) \
426static struct snd_kcontrol_new n##_control = { \
427 .iface = SNDRV_CTL_ELEM_IFACE_##type, \
428 .name = description, \
429 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
430 .info = onyx_snd_single_bit_info, \
431 .get = onyx_snd_single_bit_get, \
432 .put = onyx_snd_single_bit_put, \
433 .private_value = (flags << 16) | (address << 8) | mask \
434}
435
436SINGLE_BIT(spdif,
437 MIXER,
438 SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
439 ONYX_REG_DIG_INFO4,
440 ONYX_SPDIF_ENABLE,
441 FLAG_SPDIFLOCK);
442SINGLE_BIT(ovr1,
443 MIXER,
444 "Oversampling Rate",
445 ONYX_REG_DAC_CONTROL,
446 ONYX_OVR1,
447 0);
448SINGLE_BIT(flt0,
449 MIXER,
450 "Fast Digital Filter Rolloff",
451 ONYX_REG_DAC_FILTER,
452 ONYX_ROLLOFF_FAST,
453 FLAG_POLARITY_INVERT);
454SINGLE_BIT(hpf,
455 MIXER,
456 "Highpass Filter",
457 ONYX_REG_ADC_HPF_BYPASS,
458 ONYX_HPF_DISABLE,
459 FLAG_POLARITY_INVERT);
460SINGLE_BIT(dm12,
461 MIXER,
462 "Digital De-Emphasis",
463 ONYX_REG_DAC_DEEMPH,
464 ONYX_DIGDEEMPH_CTRL,
465 0);
466
467static int onyx_spdif_info(struct snd_kcontrol *kcontrol,
468 struct snd_ctl_elem_info *uinfo)
469{
470 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
471 uinfo->count = 1;
472 return 0;
473}
474
475static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol,
476 struct snd_ctl_elem_value *ucontrol)
477{
478 /* datasheet page 30, all others are 0 */
479 ucontrol->value.iec958.status[0] = 0x3e;
480 ucontrol->value.iec958.status[1] = 0xff;
481
482 ucontrol->value.iec958.status[3] = 0x3f;
483 ucontrol->value.iec958.status[4] = 0x0f;
484
485 return 0;
486}
487
488static struct snd_kcontrol_new onyx_spdif_mask = {
489 .access = SNDRV_CTL_ELEM_ACCESS_READ,
490 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
491 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
492 .info = onyx_spdif_info,
493 .get = onyx_spdif_mask_get,
494};
495
496static int onyx_spdif_get(struct snd_kcontrol *kcontrol,
497 struct snd_ctl_elem_value *ucontrol)
498{
499 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
500 u8 v;
501
502 mutex_lock(&onyx->mutex);
503 onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
504 ucontrol->value.iec958.status[0] = v & 0x3e;
505
506 onyx_read_register(onyx, ONYX_REG_DIG_INFO2, &v);
507 ucontrol->value.iec958.status[1] = v;
508
509 onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
510 ucontrol->value.iec958.status[3] = v & 0x3f;
511
512 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
513 ucontrol->value.iec958.status[4] = v & 0x0f;
514 mutex_unlock(&onyx->mutex);
515
516 return 0;
517}
518
519static int onyx_spdif_put(struct snd_kcontrol *kcontrol,
520 struct snd_ctl_elem_value *ucontrol)
521{
522 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
523 u8 v;
524
525 mutex_lock(&onyx->mutex);
526 onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
527 v = (v & ~0x3e) | (ucontrol->value.iec958.status[0] & 0x3e);
528 onyx_write_register(onyx, ONYX_REG_DIG_INFO1, v);
529
530 v = ucontrol->value.iec958.status[1];
531 onyx_write_register(onyx, ONYX_REG_DIG_INFO2, v);
532
533 onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
534 v = (v & ~0x3f) | (ucontrol->value.iec958.status[3] & 0x3f);
535 onyx_write_register(onyx, ONYX_REG_DIG_INFO3, v);
536
537 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
538 v = (v & ~0x0f) | (ucontrol->value.iec958.status[4] & 0x0f);
539 onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
540 mutex_unlock(&onyx->mutex);
541
542 return 1;
543}
544
545static struct snd_kcontrol_new onyx_spdif_ctrl = {
546 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
547 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
548 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
549 .info = onyx_spdif_info,
550 .get = onyx_spdif_get,
551 .put = onyx_spdif_put,
552};
553
554/* our registers */
555
556static u8 register_map[] = {
557 ONYX_REG_DAC_ATTEN_LEFT,
558 ONYX_REG_DAC_ATTEN_RIGHT,
559 ONYX_REG_CONTROL,
560 ONYX_REG_DAC_CONTROL,
561 ONYX_REG_DAC_DEEMPH,
562 ONYX_REG_DAC_FILTER,
563 ONYX_REG_DAC_OUTPHASE,
564 ONYX_REG_ADC_CONTROL,
565 ONYX_REG_ADC_HPF_BYPASS,
566 ONYX_REG_DIG_INFO1,
567 ONYX_REG_DIG_INFO2,
568 ONYX_REG_DIG_INFO3,
569 ONYX_REG_DIG_INFO4
570};
571
572static u8 initial_values[ARRAY_SIZE(register_map)] = {
573 0x80, 0x80, /* muted */
574 ONYX_MRST | ONYX_SRST, /* but handled specially! */
575 ONYX_MUTE_LEFT | ONYX_MUTE_RIGHT,
576 0, /* no deemphasis */
577 ONYX_DAC_FILTER_ALWAYS,
578 ONYX_OUTPHASE_INVERTED,
579 (-1 /*dB*/ + 8) & 0xF, /* line in selected, -1 dB gain*/
580 ONYX_ADC_HPF_ALWAYS,
581 (1<<2), /* pcm audio */
582 2, /* category: pcm coder */
583 0, /* sampling frequency 44.1 kHz, clock accuracy level II */
584 1 /* 24 bit depth */
585};
586
587/* reset registers of chip, either to initial or to previous values */
588static int onyx_register_init(struct onyx *onyx)
589{
590 int i;
591 u8 val;
592 u8 regs[sizeof(initial_values)];
593
594 if (!onyx->initialised) {
595 memcpy(regs, initial_values, sizeof(initial_values));
596 if (onyx_read_register(onyx, ONYX_REG_CONTROL, &val))
597 return -1;
598 val &= ~ONYX_SILICONVERSION;
599 val |= initial_values[3];
600 regs[3] = val;
601 } else {
602 for (i=0; i<sizeof(register_map); i++)
603 regs[i] = onyx->cache[register_map[i]-FIRSTREGISTER];
604 }
605
606 for (i=0; i<sizeof(register_map); i++) {
607 if (onyx_write_register(onyx, register_map[i], regs[i]))
608 return -1;
609 }
610 onyx->initialised = 1;
611 return 0;
612}
613
614static struct transfer_info onyx_transfers[] = {
615 /* this is first so we can skip it if no input is present...
616 * No hardware exists with that, but it's here as an example
617 * of what to do :) */
618 {
619 /* analog input */
620 .formats = SNDRV_PCM_FMTBIT_S8 |
621 SNDRV_PCM_FMTBIT_S16_BE |
622 SNDRV_PCM_FMTBIT_S24_BE,
623 .rates = SNDRV_PCM_RATE_8000_96000,
624 .transfer_in = 1,
625 .must_be_clock_source = 0,
626 .tag = 0,
627 },
628 {
629 /* if analog and digital are currently off, anything should go,
630 * so this entry describes everything we can do... */
631 .formats = SNDRV_PCM_FMTBIT_S8 |
632 SNDRV_PCM_FMTBIT_S16_BE |
633 SNDRV_PCM_FMTBIT_S24_BE
634#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
635 | SNDRV_PCM_FMTBIT_COMPRESSED_16BE
636#endif
637 ,
638 .rates = SNDRV_PCM_RATE_8000_96000,
639 .tag = 0,
640 },
641 {
642 /* analog output */
643 .formats = SNDRV_PCM_FMTBIT_S8 |
644 SNDRV_PCM_FMTBIT_S16_BE |
645 SNDRV_PCM_FMTBIT_S24_BE,
646 .rates = SNDRV_PCM_RATE_8000_96000,
647 .transfer_in = 0,
648 .must_be_clock_source = 0,
649 .tag = 1,
650 },
651 {
652 /* digital pcm output, also possible for analog out */
653 .formats = SNDRV_PCM_FMTBIT_S8 |
654 SNDRV_PCM_FMTBIT_S16_BE |
655 SNDRV_PCM_FMTBIT_S24_BE,
656 .rates = SNDRV_PCM_RATE_32000 |
657 SNDRV_PCM_RATE_44100 |
658 SNDRV_PCM_RATE_48000,
659 .transfer_in = 0,
660 .must_be_clock_source = 0,
661 .tag = 2,
662 },
663#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
664Once alsa gets supports for this kind of thing we can add it...
665 {
666 /* digital compressed output */
667 .formats = SNDRV_PCM_FMTBIT_COMPRESSED_16BE,
668 .rates = SNDRV_PCM_RATE_32000 |
669 SNDRV_PCM_RATE_44100 |
670 SNDRV_PCM_RATE_48000,
671 .tag = 2,
672 },
673#endif
674 {}
675};
676
677static int onyx_usable(struct codec_info_item *cii,
678 struct transfer_info *ti,
679 struct transfer_info *out)
680{
681 u8 v;
682 struct onyx *onyx = cii->codec_data;
683 int spdif_enabled, analog_enabled;
684
685 mutex_lock(&onyx->mutex);
686 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
687 spdif_enabled = !!(v & ONYX_SPDIF_ENABLE);
688 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
689 analog_enabled =
690 (v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT))
691 != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT);
692 mutex_unlock(&onyx->mutex);
693
694 switch (ti->tag) {
695 case 0: return 1;
696 case 1: return analog_enabled;
697 case 2: return spdif_enabled;
698 }
699 return 1;
700}
701
702static int onyx_prepare(struct codec_info_item *cii,
703 struct bus_info *bi,
704 struct snd_pcm_substream *substream)
705{
706 u8 v;
707 struct onyx *onyx = cii->codec_data;
708 int err = -EBUSY;
709
710 mutex_lock(&onyx->mutex);
711
712#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
713 if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) {
714 /* mute and lock analog output */
715 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
716 if (onyx_write_register(onyx
717 ONYX_REG_DAC_CONTROL,
718 v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT))
719 goto out_unlock;
720 onyx->analog_locked = 1;
721 err = 0;
722 goto out_unlock;
723 }
724#endif
725 switch (substream->runtime->rate) {
726 case 32000:
727 case 44100:
728 case 48000:
729 /* these rates are ok for all outputs */
730 /* FIXME: program spdif channel control bits here so that
731 * userspace doesn't have to if it only plays pcm! */
732 err = 0;
733 goto out_unlock;
734 default:
735 /* got some rate that the digital output can't do,
736 * so disable and lock it */
737 onyx_read_register(cii->codec_data, ONYX_REG_DIG_INFO4, &v);
738 if (onyx_write_register(onyx,
739 ONYX_REG_DIG_INFO4,
740 v & ~ONYX_SPDIF_ENABLE))
741 goto out_unlock;
742 onyx->spdif_locked = 1;
743 err = 0;
744 goto out_unlock;
745 }
746
747 out_unlock:
748 mutex_unlock(&onyx->mutex);
749
750 return err;
751}
752
753static int onyx_open(struct codec_info_item *cii,
754 struct snd_pcm_substream *substream)
755{
756 struct onyx *onyx = cii->codec_data;
757
758 mutex_lock(&onyx->mutex);
759 onyx->open_count++;
760 mutex_unlock(&onyx->mutex);
761
762 return 0;
763}
764
765static int onyx_close(struct codec_info_item *cii,
766 struct snd_pcm_substream *substream)
767{
768 struct onyx *onyx = cii->codec_data;
769
770 mutex_lock(&onyx->mutex);
771 onyx->open_count--;
772 if (!onyx->open_count)
773 onyx->spdif_locked = onyx->analog_locked = 0;
774 mutex_unlock(&onyx->mutex);
775
776 return 0;
777}
778
779static int onyx_switch_clock(struct codec_info_item *cii,
780 enum clock_switch what)
781{
782 struct onyx *onyx = cii->codec_data;
783
784 mutex_lock(&onyx->mutex);
785 /* this *MUST* be more elaborate later... */
786 switch (what) {
787 case CLOCK_SWITCH_PREPARE_SLAVE:
788 onyx->codec.gpio->methods->all_amps_off(onyx->codec.gpio);
789 break;
790 case CLOCK_SWITCH_SLAVE:
791 onyx->codec.gpio->methods->all_amps_restore(onyx->codec.gpio);
792 break;
793 default: /* silence warning */
794 break;
795 }
796 mutex_unlock(&onyx->mutex);
797
798 return 0;
799}
800
801#ifdef CONFIG_PM
802
803static int onyx_suspend(struct codec_info_item *cii, pm_message_t state)
804{
805 struct onyx *onyx = cii->codec_data;
806 u8 v;
807 int err = -ENXIO;
808
809 mutex_lock(&onyx->mutex);
810 if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
811 goto out_unlock;
812 onyx_write_register(onyx, ONYX_REG_CONTROL, v | ONYX_ADPSV | ONYX_DAPSV);
813 /* Apple does a sleep here but the datasheet says to do it on resume */
814 err = 0;
815 out_unlock:
816 mutex_unlock(&onyx->mutex);
817
818 return err;
819}
820
821static int onyx_resume(struct codec_info_item *cii)
822{
823 struct onyx *onyx = cii->codec_data;
824 u8 v;
825 int err = -ENXIO;
826
827 mutex_lock(&onyx->mutex);
828 /* take codec out of suspend */
829 if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
830 goto out_unlock;
831 onyx_write_register(onyx, ONYX_REG_CONTROL, v & ~(ONYX_ADPSV | ONYX_DAPSV));
832 /* FIXME: should divide by sample rate, but 8k is the lowest we go */
833 msleep(2205000/8000);
834 /* reset all values */
835 onyx_register_init(onyx);
836 err = 0;
837 out_unlock:
838 mutex_unlock(&onyx->mutex);
839
840 return err;
841}
842
843#endif /* CONFIG_PM */
844
845static struct codec_info onyx_codec_info = {
846 .transfers = onyx_transfers,
847 .sysclock_factor = 256,
848 .bus_factor = 64,
849 .owner = THIS_MODULE,
850 .usable = onyx_usable,
851 .prepare = onyx_prepare,
852 .open = onyx_open,
853 .close = onyx_close,
854 .switch_clock = onyx_switch_clock,
855#ifdef CONFIG_PM
856 .suspend = onyx_suspend,
857 .resume = onyx_resume,
858#endif
859};
860
861static int onyx_init_codec(struct aoa_codec *codec)
862{
863 struct onyx *onyx = codec_to_onyx(codec);
864 struct snd_kcontrol *ctl;
865 struct codec_info *ci = &onyx_codec_info;
866 u8 v;
867 int err;
868
869 if (!onyx->codec.gpio || !onyx->codec.gpio->methods) {
870 printk(KERN_ERR PFX "gpios not assigned!!\n");
871 return -EINVAL;
872 }
873
874 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
875 msleep(1);
876 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1);
877 msleep(1);
878 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
879 msleep(1);
880
881 if (onyx_register_init(onyx)) {
882 printk(KERN_ERR PFX "failed to initialise onyx registers\n");
883 return -ENODEV;
884 }
885
886 if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, onyx, &ops)) {
887 printk(KERN_ERR PFX "failed to create onyx snd device!\n");
888 return -ENODEV;
889 }
890
891 /* nothing connected? what a joke! */
892 if ((onyx->codec.connected & 0xF) == 0)
893 return -ENOTCONN;
894
895 /* if no inputs are present... */
896 if ((onyx->codec.connected & 0xC) == 0) {
897 if (!onyx->codec_info)
898 onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
899 if (!onyx->codec_info)
900 return -ENOMEM;
901 ci = onyx->codec_info;
902 *ci = onyx_codec_info;
903 ci->transfers++;
904 }
905
906 /* if no outputs are present... */
907 if ((onyx->codec.connected & 3) == 0) {
908 if (!onyx->codec_info)
909 onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
910 if (!onyx->codec_info)
911 return -ENOMEM;
912 ci = onyx->codec_info;
913 /* this is fine as there have to be inputs
914 * if we end up in this part of the code */
915 *ci = onyx_codec_info;
916 ci->transfers[1].formats = 0;
917 }
918
919 if (onyx->codec.soundbus_dev->attach_codec(onyx->codec.soundbus_dev,
920 aoa_get_card(),
921 ci, onyx)) {
922 printk(KERN_ERR PFX "error creating onyx pcm\n");
923 return -ENODEV;
924 }
925#define ADDCTL(n) \
926 do { \
927 ctl = snd_ctl_new1(&n, onyx); \
928 if (ctl) { \
929 ctl->id.device = \
930 onyx->codec.soundbus_dev->pcm->device; \
931 err = aoa_snd_ctl_add(ctl); \
932 if (err) \
933 goto error; \
934 } \
935 } while (0)
936
937 if (onyx->codec.soundbus_dev->pcm) {
938 /* give the user appropriate controls
939 * depending on what inputs are connected */
940 if ((onyx->codec.connected & 0xC) == 0xC)
941 ADDCTL(capture_source_control);
942 else if (onyx->codec.connected & 4)
943 onyx_set_capture_source(onyx, 0);
944 else
945 onyx_set_capture_source(onyx, 1);
946 if (onyx->codec.connected & 0xC)
947 ADDCTL(inputgain_control);
948
949 /* depending on what output is connected,
950 * give the user appropriate controls */
951 if (onyx->codec.connected & 1) {
952 ADDCTL(volume_control);
953 ADDCTL(mute_control);
954 ADDCTL(ovr1_control);
955 ADDCTL(flt0_control);
956 ADDCTL(hpf_control);
957 ADDCTL(dm12_control);
958 /* spdif control defaults to off */
959 }
960 if (onyx->codec.connected & 2) {
961 ADDCTL(onyx_spdif_mask);
962 ADDCTL(onyx_spdif_ctrl);
963 }
964 if ((onyx->codec.connected & 3) == 3)
965 ADDCTL(spdif_control);
966 /* if only S/PDIF is connected, enable it unconditionally */
967 if ((onyx->codec.connected & 3) == 2) {
968 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
969 v |= ONYX_SPDIF_ENABLE;
970 onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
971 }
972 }
973#undef ADDCTL
974 printk(KERN_INFO PFX "attached to onyx codec via i2c\n");
975
976 return 0;
977 error:
978 onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
979 snd_device_free(aoa_get_card(), onyx);
980 return err;
981}
982
983static void onyx_exit_codec(struct aoa_codec *codec)
984{
985 struct onyx *onyx = codec_to_onyx(codec);
986
987 if (!onyx->codec.soundbus_dev) {
988 printk(KERN_ERR PFX "onyx_exit_codec called without soundbus_dev!\n");
989 return;
990 }
991 onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
992}
993
994static struct i2c_driver onyx_driver;
995
996static int onyx_create(struct i2c_adapter *adapter,
997 struct device_node *node,
998 int addr)
999{
1000 struct onyx *onyx;
1001 u8 dummy;
1002
1003 onyx = kzalloc(sizeof(struct onyx), GFP_KERNEL);
1004
1005 if (!onyx)
1006 return -ENOMEM;
1007
1008 mutex_init(&onyx->mutex);
1009 onyx->i2c.driver = &onyx_driver;
1010 onyx->i2c.adapter = adapter;
1011 onyx->i2c.addr = addr & 0x7f;
1012 strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE-1);
1013
1014 if (i2c_attach_client(&onyx->i2c)) {
1015 printk(KERN_ERR PFX "failed to attach to i2c\n");
1016 goto fail;
1017 }
1018
1019 /* we try to read from register ONYX_REG_CONTROL
1020 * to check if the codec is present */
1021 if (onyx_read_register(onyx, ONYX_REG_CONTROL, &dummy) != 0) {
1022 i2c_detach_client(&onyx->i2c);
1023 printk(KERN_ERR PFX "failed to read control register\n");
1024 goto fail;
1025 }
1026
1027 strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN-1);
1028 onyx->codec.owner = THIS_MODULE;
1029 onyx->codec.init = onyx_init_codec;
1030 onyx->codec.exit = onyx_exit_codec;
1031 onyx->codec.node = of_node_get(node);
1032
1033 if (aoa_codec_register(&onyx->codec)) {
1034 i2c_detach_client(&onyx->i2c);
1035 goto fail;
1036 }
1037 printk(KERN_DEBUG PFX "created and attached onyx instance\n");
1038 return 0;
1039 fail:
1040 kfree(onyx);
1041 return -EINVAL;
1042}
1043
1044static int onyx_i2c_attach(struct i2c_adapter *adapter)
1045{
1046 struct device_node *busnode, *dev = NULL;
1047 struct pmac_i2c_bus *bus;
1048
1049 bus = pmac_i2c_adapter_to_bus(adapter);
1050 if (bus == NULL)
1051 return -ENODEV;
1052 busnode = pmac_i2c_get_bus_node(bus);
1053
1054 while ((dev = of_get_next_child(busnode, dev)) != NULL) {
1055 if (device_is_compatible(dev, "pcm3052")) {
1056 u32 *addr;
1057 printk(KERN_DEBUG PFX "found pcm3052\n");
1058 addr = (u32 *) get_property(dev, "reg", NULL);
1059 if (!addr)
1060 return -ENODEV;
1061 return onyx_create(adapter, dev, (*addr)>>1);
1062 }
1063 }
1064
1065 /* if that didn't work, try desperate mode for older
1066 * machines that have stuff missing from the device tree */
1067
1068 if (!device_is_compatible(busnode, "k2-i2c"))
1069 return -ENODEV;
1070
1071 printk(KERN_DEBUG PFX "found k2-i2c, checking if onyx chip is on it\n");
1072 /* probe both possible addresses for the onyx chip */
1073 if (onyx_create(adapter, NULL, 0x46) == 0)
1074 return 0;
1075 return onyx_create(adapter, NULL, 0x47);
1076}
1077
1078static int onyx_i2c_detach(struct i2c_client *client)
1079{
1080 struct onyx *onyx = container_of(client, struct onyx, i2c);
1081 int err;
1082
1083 if ((err = i2c_detach_client(client)))
1084 return err;
1085 aoa_codec_unregister(&onyx->codec);
1086 of_node_put(onyx->codec.node);
1087 if (onyx->codec_info)
1088 kfree(onyx->codec_info);
1089 kfree(onyx);
1090 return 0;
1091}
1092
1093static struct i2c_driver onyx_driver = {
1094 .driver = {
1095 .name = "aoa_codec_onyx",
1096 .owner = THIS_MODULE,
1097 },
1098 .attach_adapter = onyx_i2c_attach,
1099 .detach_client = onyx_i2c_detach,
1100};
1101
1102static int __init onyx_init(void)
1103{
1104 return i2c_add_driver(&onyx_driver);
1105}
1106
1107static void __exit onyx_exit(void)
1108{
1109 i2c_del_driver(&onyx_driver);
1110}
1111
1112module_init(onyx_init);
1113module_exit(onyx_exit);
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.h b/sound/aoa/codecs/snd-aoa-codec-onyx.h
new file mode 100644
index 000000000000..aeedda773699
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-onyx.h
@@ -0,0 +1,76 @@
1/*
2 * Apple Onboard Audio driver for Onyx codec (header)
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#ifndef __SND_AOA_CODEC_ONYX_H
9#define __SND_AOA_CODEC_ONYX_H
10#include <stddef.h>
11#include <linux/i2c.h>
12#include <linux/i2c-dev.h>
13#include <asm/pmac_low_i2c.h>
14#include <asm/prom.h>
15
16/* PCM3052 register definitions */
17
18/* the attenuation registers take values from
19 * -1 (0dB) to -127 (-63.0 dB) or others (muted) */
20#define ONYX_REG_DAC_ATTEN_LEFT 65
21#define FIRSTREGISTER ONYX_REG_DAC_ATTEN_LEFT
22#define ONYX_REG_DAC_ATTEN_RIGHT 66
23
24#define ONYX_REG_CONTROL 67
25# define ONYX_MRST (1<<7)
26# define ONYX_SRST (1<<6)
27# define ONYX_ADPSV (1<<5)
28# define ONYX_DAPSV (1<<4)
29# define ONYX_SILICONVERSION (1<<0)
30/* all others reserved */
31
32#define ONYX_REG_DAC_CONTROL 68
33# define ONYX_OVR1 (1<<6)
34# define ONYX_MUTE_RIGHT (1<<1)
35# define ONYX_MUTE_LEFT (1<<0)
36
37#define ONYX_REG_DAC_DEEMPH 69
38# define ONYX_DIGDEEMPH_SHIFT 5
39# define ONYX_DIGDEEMPH_MASK (3<<ONYX_DIGDEEMPH_SHIFT)
40# define ONYX_DIGDEEMPH_CTRL (1<<4)
41
42#define ONYX_REG_DAC_FILTER 70
43# define ONYX_ROLLOFF_FAST (1<<5)
44# define ONYX_DAC_FILTER_ALWAYS (1<<2)
45
46#define ONYX_REG_DAC_OUTPHASE 71
47# define ONYX_OUTPHASE_INVERTED (1<<0)
48
49#define ONYX_REG_ADC_CONTROL 72
50# define ONYX_ADC_INPUT_MIC (1<<5)
51/* 8 + input gain in dB, valid range for input gain is -4 .. 20 dB */
52# define ONYX_ADC_PGA_GAIN_MASK 0x1f
53
54#define ONYX_REG_ADC_HPF_BYPASS 75
55# define ONYX_HPF_DISABLE (1<<3)
56# define ONYX_ADC_HPF_ALWAYS (1<<2)
57
58#define ONYX_REG_DIG_INFO1 77
59# define ONYX_MASK_DIN_TO_BPZ (1<<7)
60/* bits 1-5 control channel bits 1-5 */
61# define ONYX_DIGOUT_DISABLE (1<<0)
62
63#define ONYX_REG_DIG_INFO2 78
64/* controls channel bits 8-15 */
65
66#define ONYX_REG_DIG_INFO3 79
67/* control channel bits 24-29, high 2 bits reserved */
68
69#define ONYX_REG_DIG_INFO4 80
70# define ONYX_VALIDL (1<<7)
71# define ONYX_VALIDR (1<<6)
72# define ONYX_SPDIF_ENABLE (1<<5)
73/* lower 4 bits control bits 32-35 of channel control and word length */
74# define ONYX_WORDLEN_MASK (0xF)
75
76#endif /* __SND_AOA_CODEC_ONYX_H */
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h b/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h
new file mode 100644
index 000000000000..4cfa6757715e
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h
@@ -0,0 +1,209 @@
1/*
2 This is the program used to generate below table.
3
4#include <stdio.h>
5#include <math.h>
6int main() {
7 int dB2;
8 printf("/" "* This file is only included exactly once!\n");
9 printf(" *\n");
10 printf(" * If they'd only tell us that generating this table was\n");
11 printf(" * as easy as calculating\n");
12 printf(" * hwvalue = 1048576.0*exp(0.057564628*dB*2)\n");
13 printf(" * :) *" "/\n");
14 printf("static int tas_gaintable[] = {\n");
15 printf(" 0x000000, /" "* -infinity dB *" "/\n");
16 for (dB2=-140;dB2<=36;dB2++)
17 printf(" 0x%.6x, /" "* %-02.1f dB *" "/\n", (int)(1048576.0*exp(0.057564628*dB2)), dB2/2.0);
18 printf("};\n\n");
19}
20
21*/
22
23/* This file is only included exactly once!
24 *
25 * If they'd only tell us that generating this table was
26 * as easy as calculating
27 * hwvalue = 1048576.0*exp(0.057564628*dB*2)
28 * :) */
29static int tas_gaintable[] = {
30 0x000000, /* -infinity dB */
31 0x00014b, /* -70.0 dB */
32 0x00015f, /* -69.5 dB */
33 0x000174, /* -69.0 dB */
34 0x00018a, /* -68.5 dB */
35 0x0001a1, /* -68.0 dB */
36 0x0001ba, /* -67.5 dB */
37 0x0001d4, /* -67.0 dB */
38 0x0001f0, /* -66.5 dB */
39 0x00020d, /* -66.0 dB */
40 0x00022c, /* -65.5 dB */
41 0x00024d, /* -65.0 dB */
42 0x000270, /* -64.5 dB */
43 0x000295, /* -64.0 dB */
44 0x0002bc, /* -63.5 dB */
45 0x0002e6, /* -63.0 dB */
46 0x000312, /* -62.5 dB */
47 0x000340, /* -62.0 dB */
48 0x000372, /* -61.5 dB */
49 0x0003a6, /* -61.0 dB */
50 0x0003dd, /* -60.5 dB */
51 0x000418, /* -60.0 dB */
52 0x000456, /* -59.5 dB */
53 0x000498, /* -59.0 dB */
54 0x0004de, /* -58.5 dB */
55 0x000528, /* -58.0 dB */
56 0x000576, /* -57.5 dB */
57 0x0005c9, /* -57.0 dB */
58 0x000620, /* -56.5 dB */
59 0x00067d, /* -56.0 dB */
60 0x0006e0, /* -55.5 dB */
61 0x000748, /* -55.0 dB */
62 0x0007b7, /* -54.5 dB */
63 0x00082c, /* -54.0 dB */
64 0x0008a8, /* -53.5 dB */
65 0x00092b, /* -53.0 dB */
66 0x0009b6, /* -52.5 dB */
67 0x000a49, /* -52.0 dB */
68 0x000ae5, /* -51.5 dB */
69 0x000b8b, /* -51.0 dB */
70 0x000c3a, /* -50.5 dB */
71 0x000cf3, /* -50.0 dB */
72 0x000db8, /* -49.5 dB */
73 0x000e88, /* -49.0 dB */
74 0x000f64, /* -48.5 dB */
75 0x00104e, /* -48.0 dB */
76 0x001145, /* -47.5 dB */
77 0x00124b, /* -47.0 dB */
78 0x001361, /* -46.5 dB */
79 0x001487, /* -46.0 dB */
80 0x0015be, /* -45.5 dB */
81 0x001708, /* -45.0 dB */
82 0x001865, /* -44.5 dB */
83 0x0019d8, /* -44.0 dB */
84 0x001b60, /* -43.5 dB */
85 0x001cff, /* -43.0 dB */
86 0x001eb7, /* -42.5 dB */
87 0x002089, /* -42.0 dB */
88 0x002276, /* -41.5 dB */
89 0x002481, /* -41.0 dB */
90 0x0026ab, /* -40.5 dB */
91 0x0028f5, /* -40.0 dB */
92 0x002b63, /* -39.5 dB */
93 0x002df5, /* -39.0 dB */
94 0x0030ae, /* -38.5 dB */
95 0x003390, /* -38.0 dB */
96 0x00369e, /* -37.5 dB */
97 0x0039db, /* -37.0 dB */
98 0x003d49, /* -36.5 dB */
99 0x0040ea, /* -36.0 dB */
100 0x0044c3, /* -35.5 dB */
101 0x0048d6, /* -35.0 dB */
102 0x004d27, /* -34.5 dB */
103 0x0051b9, /* -34.0 dB */
104 0x005691, /* -33.5 dB */
105 0x005bb2, /* -33.0 dB */
106 0x006121, /* -32.5 dB */
107 0x0066e3, /* -32.0 dB */
108 0x006cfb, /* -31.5 dB */
109 0x007370, /* -31.0 dB */
110 0x007a48, /* -30.5 dB */
111 0x008186, /* -30.0 dB */
112 0x008933, /* -29.5 dB */
113 0x009154, /* -29.0 dB */
114 0x0099f1, /* -28.5 dB */
115 0x00a310, /* -28.0 dB */
116 0x00acba, /* -27.5 dB */
117 0x00b6f6, /* -27.0 dB */
118 0x00c1cd, /* -26.5 dB */
119 0x00cd49, /* -26.0 dB */
120 0x00d973, /* -25.5 dB */
121 0x00e655, /* -25.0 dB */
122 0x00f3fb, /* -24.5 dB */
123 0x010270, /* -24.0 dB */
124 0x0111c0, /* -23.5 dB */
125 0x0121f9, /* -23.0 dB */
126 0x013328, /* -22.5 dB */
127 0x01455b, /* -22.0 dB */
128 0x0158a2, /* -21.5 dB */
129 0x016d0e, /* -21.0 dB */
130 0x0182af, /* -20.5 dB */
131 0x019999, /* -20.0 dB */
132 0x01b1de, /* -19.5 dB */
133 0x01cb94, /* -19.0 dB */
134 0x01e6cf, /* -18.5 dB */
135 0x0203a7, /* -18.0 dB */
136 0x022235, /* -17.5 dB */
137 0x024293, /* -17.0 dB */
138 0x0264db, /* -16.5 dB */
139 0x02892c, /* -16.0 dB */
140 0x02afa3, /* -15.5 dB */
141 0x02d862, /* -15.0 dB */
142 0x03038a, /* -14.5 dB */
143 0x033142, /* -14.0 dB */
144 0x0361af, /* -13.5 dB */
145 0x0394fa, /* -13.0 dB */
146 0x03cb50, /* -12.5 dB */
147 0x0404de, /* -12.0 dB */
148 0x0441d5, /* -11.5 dB */
149 0x048268, /* -11.0 dB */
150 0x04c6d0, /* -10.5 dB */
151 0x050f44, /* -10.0 dB */
152 0x055c04, /* -9.5 dB */
153 0x05ad50, /* -9.0 dB */
154 0x06036e, /* -8.5 dB */
155 0x065ea5, /* -8.0 dB */
156 0x06bf44, /* -7.5 dB */
157 0x07259d, /* -7.0 dB */
158 0x079207, /* -6.5 dB */
159 0x0804dc, /* -6.0 dB */
160 0x087e80, /* -5.5 dB */
161 0x08ff59, /* -5.0 dB */
162 0x0987d5, /* -4.5 dB */
163 0x0a1866, /* -4.0 dB */
164 0x0ab189, /* -3.5 dB */
165 0x0b53be, /* -3.0 dB */
166 0x0bff91, /* -2.5 dB */
167 0x0cb591, /* -2.0 dB */
168 0x0d765a, /* -1.5 dB */
169 0x0e4290, /* -1.0 dB */
170 0x0f1adf, /* -0.5 dB */
171 0x100000, /* 0.0 dB */
172 0x10f2b4, /* 0.5 dB */
173 0x11f3c9, /* 1.0 dB */
174 0x13041a, /* 1.5 dB */
175 0x14248e, /* 2.0 dB */
176 0x15561a, /* 2.5 dB */
177 0x1699c0, /* 3.0 dB */
178 0x17f094, /* 3.5 dB */
179 0x195bb8, /* 4.0 dB */
180 0x1adc61, /* 4.5 dB */
181 0x1c73d5, /* 5.0 dB */
182 0x1e236d, /* 5.5 dB */
183 0x1fec98, /* 6.0 dB */
184 0x21d0d9, /* 6.5 dB */
185 0x23d1cd, /* 7.0 dB */
186 0x25f125, /* 7.5 dB */
187 0x2830af, /* 8.0 dB */
188 0x2a9254, /* 8.5 dB */
189 0x2d1818, /* 9.0 dB */
190 0x2fc420, /* 9.5 dB */
191 0x3298b0, /* 10.0 dB */
192 0x35982f, /* 10.5 dB */
193 0x38c528, /* 11.0 dB */
194 0x3c224c, /* 11.5 dB */
195 0x3fb278, /* 12.0 dB */
196 0x4378b0, /* 12.5 dB */
197 0x477829, /* 13.0 dB */
198 0x4bb446, /* 13.5 dB */
199 0x5030a1, /* 14.0 dB */
200 0x54f106, /* 14.5 dB */
201 0x59f980, /* 15.0 dB */
202 0x5f4e52, /* 15.5 dB */
203 0x64f403, /* 16.0 dB */
204 0x6aef5e, /* 16.5 dB */
205 0x714575, /* 17.0 dB */
206 0x77fbaa, /* 17.5 dB */
207 0x7f17af, /* 18.0 dB */
208};
209
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c
new file mode 100644
index 000000000000..2e39ff6ee349
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.c
@@ -0,0 +1,654 @@
1/*
2 * Apple Onboard Audio driver for tas codec
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 *
8 * Open questions:
9 * - How to distinguish between 3004 and versions?
10 *
11 * FIXMEs:
12 * - This codec driver doesn't honour the 'connected'
13 * property of the aoa_codec struct, hence if
14 * it is used in machines where not everything is
15 * connected it will display wrong mixer elements.
16 * - Driver assumes that the microphone is always
17 * monaureal and connected to the right channel of
18 * the input. This should also be a codec-dependent
19 * flag, maybe the codec should have 3 different
20 * bits for the three different possibilities how
21 * it can be hooked up...
22 * But as long as I don't see any hardware hooked
23 * up that way...
24 * - As Apple notes in their code, the tas3004 seems
25 * to delay the right channel by one sample. You can
26 * see this when for example recording stereo in
27 * audacity, or recording the tas output via cable
28 * on another machine (use a sinus generator or so).
29 * I tried programming the BiQuads but couldn't
30 * make the delay work, maybe someone can read the
31 * datasheet and fix it. The relevant Apple comment
32 * is in AppleTAS3004Audio.cpp lines 1637 ff. Note
33 * that their comment describing how they program
34 * the filters sucks...
35 *
36 * Other things:
37 * - this should actually register *two* aoa_codec
38 * structs since it has two inputs. Then it must
39 * use the prepare callback to forbid running the
40 * secondary output on a different clock.
41 * Also, whatever bus knows how to do this must
42 * provide two soundbus_dev devices and the fabric
43 * must be able to link them correctly.
44 *
45 * I don't even know if Apple ever uses the second
46 * port on the tas3004 though, I don't think their
47 * i2s controllers can even do it. OTOH, they all
48 * derive the clocks from common clocks, so it
49 * might just be possible. The framework allows the
50 * codec to refine the transfer_info items in the
51 * usable callback, so we can simply remove the
52 * rates the second instance is not using when it
53 * actually is in use.
54 * Maybe we'll need to make the sound busses have
55 * a 'clock group id' value so the codec can
56 * determine if the two outputs can be driven at
57 * the same time. But that is likely overkill, up
58 * to the fabric to not link them up incorrectly,
59 * and up to the hardware designer to not wire
60 * them up in some weird unusable way.
61 */
62#include <stddef.h>
63#include <linux/i2c.h>
64#include <linux/i2c-dev.h>
65#include <asm/pmac_low_i2c.h>
66#include <asm/prom.h>
67#include <linux/delay.h>
68#include <linux/module.h>
69MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
70MODULE_LICENSE("GPL");
71MODULE_DESCRIPTION("tas codec driver for snd-aoa");
72
73#include "snd-aoa-codec-tas.h"
74#include "snd-aoa-codec-tas-gain-table.h"
75#include "../aoa.h"
76#include "../soundbus/soundbus.h"
77
78
79#define PFX "snd-aoa-codec-tas: "
80
81struct tas {
82 struct aoa_codec codec;
83 struct i2c_client i2c;
84 u32 muted_l:1, muted_r:1,
85 controls_created:1;
86 u8 cached_volume_l, cached_volume_r;
87 u8 mixer_l[3], mixer_r[3];
88 u8 acr;
89};
90
91static struct tas *codec_to_tas(struct aoa_codec *codec)
92{
93 return container_of(codec, struct tas, codec);
94}
95
96static inline int tas_write_reg(struct tas *tas, u8 reg, u8 len, u8 *data)
97{
98 if (len == 1)
99 return i2c_smbus_write_byte_data(&tas->i2c, reg, *data);
100 else
101 return i2c_smbus_write_i2c_block_data(&tas->i2c, reg, len, data);
102}
103
104static void tas_set_volume(struct tas *tas)
105{
106 u8 block[6];
107 int tmp;
108 u8 left, right;
109
110 left = tas->cached_volume_l;
111 right = tas->cached_volume_r;
112
113 if (left > 177) left = 177;
114 if (right > 177) right = 177;
115
116 if (tas->muted_l) left = 0;
117 if (tas->muted_r) right = 0;
118
119 /* analysing the volume and mixer tables shows
120 * that they are similar enough when we shift
121 * the mixer table down by 4 bits. The error
122 * is miniscule, in just one item the error
123 * is 1, at a value of 0x07f17b (mixer table
124 * value is 0x07f17a) */
125 tmp = tas_gaintable[left];
126 block[0] = tmp>>20;
127 block[1] = tmp>>12;
128 block[2] = tmp>>4;
129 tmp = tas_gaintable[right];
130 block[3] = tmp>>20;
131 block[4] = tmp>>12;
132 block[5] = tmp>>4;
133 tas_write_reg(tas, TAS_REG_VOL, 6, block);
134}
135
136static void tas_set_mixer(struct tas *tas)
137{
138 u8 block[9];
139 int tmp, i;
140 u8 val;
141
142 for (i=0;i<3;i++) {
143 val = tas->mixer_l[i];
144 if (val > 177) val = 177;
145 tmp = tas_gaintable[val];
146 block[3*i+0] = tmp>>16;
147 block[3*i+1] = tmp>>8;
148 block[3*i+2] = tmp;
149 }
150 tas_write_reg(tas, TAS_REG_LMIX, 9, block);
151
152 for (i=0;i<3;i++) {
153 val = tas->mixer_r[i];
154 if (val > 177) val = 177;
155 tmp = tas_gaintable[val];
156 block[3*i+0] = tmp>>16;
157 block[3*i+1] = tmp>>8;
158 block[3*i+2] = tmp;
159 }
160 tas_write_reg(tas, TAS_REG_RMIX, 9, block);
161}
162
163/* alsa stuff */
164
165static int tas_dev_register(struct snd_device *dev)
166{
167 return 0;
168}
169
170static struct snd_device_ops ops = {
171 .dev_register = tas_dev_register,
172};
173
174static int tas_snd_vol_info(struct snd_kcontrol *kcontrol,
175 struct snd_ctl_elem_info *uinfo)
176{
177 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
178 uinfo->count = 2;
179 uinfo->value.integer.min = 0;
180 uinfo->value.integer.max = 177;
181 return 0;
182}
183
184static int tas_snd_vol_get(struct snd_kcontrol *kcontrol,
185 struct snd_ctl_elem_value *ucontrol)
186{
187 struct tas *tas = snd_kcontrol_chip(kcontrol);
188
189 ucontrol->value.integer.value[0] = tas->cached_volume_l;
190 ucontrol->value.integer.value[1] = tas->cached_volume_r;
191 return 0;
192}
193
194static int tas_snd_vol_put(struct snd_kcontrol *kcontrol,
195 struct snd_ctl_elem_value *ucontrol)
196{
197 struct tas *tas = snd_kcontrol_chip(kcontrol);
198
199 if (tas->cached_volume_l == ucontrol->value.integer.value[0]
200 && tas->cached_volume_r == ucontrol->value.integer.value[1])
201 return 0;
202
203 tas->cached_volume_l = ucontrol->value.integer.value[0];
204 tas->cached_volume_r = ucontrol->value.integer.value[1];
205 tas_set_volume(tas);
206 return 1;
207}
208
209static struct snd_kcontrol_new volume_control = {
210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
211 .name = "Master Playback Volume",
212 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
213 .info = tas_snd_vol_info,
214 .get = tas_snd_vol_get,
215 .put = tas_snd_vol_put,
216};
217
218static int tas_snd_mute_info(struct snd_kcontrol *kcontrol,
219 struct snd_ctl_elem_info *uinfo)
220{
221 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
222 uinfo->count = 2;
223 uinfo->value.integer.min = 0;
224 uinfo->value.integer.max = 1;
225 return 0;
226}
227
228static int tas_snd_mute_get(struct snd_kcontrol *kcontrol,
229 struct snd_ctl_elem_value *ucontrol)
230{
231 struct tas *tas = snd_kcontrol_chip(kcontrol);
232
233 ucontrol->value.integer.value[0] = !tas->muted_l;
234 ucontrol->value.integer.value[1] = !tas->muted_r;
235 return 0;
236}
237
238static int tas_snd_mute_put(struct snd_kcontrol *kcontrol,
239 struct snd_ctl_elem_value *ucontrol)
240{
241 struct tas *tas = snd_kcontrol_chip(kcontrol);
242
243 if (tas->muted_l == !ucontrol->value.integer.value[0]
244 && tas->muted_r == !ucontrol->value.integer.value[1])
245 return 0;
246
247 tas->muted_l = !ucontrol->value.integer.value[0];
248 tas->muted_r = !ucontrol->value.integer.value[1];
249 tas_set_volume(tas);
250 return 1;
251}
252
253static struct snd_kcontrol_new mute_control = {
254 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
255 .name = "Master Playback Switch",
256 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
257 .info = tas_snd_mute_info,
258 .get = tas_snd_mute_get,
259 .put = tas_snd_mute_put,
260};
261
262static int tas_snd_mixer_info(struct snd_kcontrol *kcontrol,
263 struct snd_ctl_elem_info *uinfo)
264{
265 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
266 uinfo->count = 2;
267 uinfo->value.integer.min = 0;
268 uinfo->value.integer.max = 177;
269 return 0;
270}
271
272static int tas_snd_mixer_get(struct snd_kcontrol *kcontrol,
273 struct snd_ctl_elem_value *ucontrol)
274{
275 struct tas *tas = snd_kcontrol_chip(kcontrol);
276 int idx = kcontrol->private_value;
277
278 ucontrol->value.integer.value[0] = tas->mixer_l[idx];
279 ucontrol->value.integer.value[1] = tas->mixer_r[idx];
280
281 return 0;
282}
283
284static int tas_snd_mixer_put(struct snd_kcontrol *kcontrol,
285 struct snd_ctl_elem_value *ucontrol)
286{
287 struct tas *tas = snd_kcontrol_chip(kcontrol);
288 int idx = kcontrol->private_value;
289
290 if (tas->mixer_l[idx] == ucontrol->value.integer.value[0]
291 && tas->mixer_r[idx] == ucontrol->value.integer.value[1])
292 return 0;
293
294 tas->mixer_l[idx] = ucontrol->value.integer.value[0];
295 tas->mixer_r[idx] = ucontrol->value.integer.value[1];
296
297 tas_set_mixer(tas);
298 return 1;
299}
300
301#define MIXER_CONTROL(n,descr,idx) \
302static struct snd_kcontrol_new n##_control = { \
303 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
304 .name = descr " Playback Volume", \
305 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
306 .info = tas_snd_mixer_info, \
307 .get = tas_snd_mixer_get, \
308 .put = tas_snd_mixer_put, \
309 .private_value = idx, \
310}
311
312MIXER_CONTROL(pcm1, "PCM1", 0);
313MIXER_CONTROL(monitor, "Monitor", 2);
314
315static int tas_snd_capture_source_info(struct snd_kcontrol *kcontrol,
316 struct snd_ctl_elem_info *uinfo)
317{
318 static char *texts[] = { "Line-In", "Microphone" };
319
320 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
321 uinfo->count = 1;
322 uinfo->value.enumerated.items = 2;
323 if (uinfo->value.enumerated.item > 1)
324 uinfo->value.enumerated.item = 1;
325 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
326 return 0;
327}
328
329static int tas_snd_capture_source_get(struct snd_kcontrol *kcontrol,
330 struct snd_ctl_elem_value *ucontrol)
331{
332 struct tas *tas = snd_kcontrol_chip(kcontrol);
333
334 ucontrol->value.enumerated.item[0] = !!(tas->acr & TAS_ACR_INPUT_B);
335 return 0;
336}
337
338static int tas_snd_capture_source_put(struct snd_kcontrol *kcontrol,
339 struct snd_ctl_elem_value *ucontrol)
340{
341 struct tas *tas = snd_kcontrol_chip(kcontrol);
342 int oldacr = tas->acr;
343
344 tas->acr &= ~TAS_ACR_INPUT_B;
345 if (ucontrol->value.enumerated.item[0])
346 tas->acr |= TAS_ACR_INPUT_B;
347 if (oldacr == tas->acr)
348 return 0;
349 tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
350 return 1;
351}
352
353static struct snd_kcontrol_new capture_source_control = {
354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
355 /* If we name this 'Input Source', it properly shows up in
356 * alsamixer as a selection, * but it's shown under the
357 * 'Playback' category.
358 * If I name it 'Capture Source', it shows up in strange
359 * ways (two bools of which one can be selected at a
360 * time) but at least it's shown in the 'Capture'
361 * category.
362 * I was told that this was due to backward compatibility,
363 * but I don't understand then why the mangling is *not*
364 * done when I name it "Input Source".....
365 */
366 .name = "Capture Source",
367 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
368 .info = tas_snd_capture_source_info,
369 .get = tas_snd_capture_source_get,
370 .put = tas_snd_capture_source_put,
371};
372
373
374static struct transfer_info tas_transfers[] = {
375 {
376 /* input */
377 .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_BE |
378 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE,
379 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
380 .transfer_in = 1,
381 },
382 {
383 /* output */
384 .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_BE |
385 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE,
386 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
387 .transfer_in = 0,
388 },
389 {}
390};
391
392static int tas_usable(struct codec_info_item *cii,
393 struct transfer_info *ti,
394 struct transfer_info *out)
395{
396 return 1;
397}
398
399static int tas_reset_init(struct tas *tas)
400{
401 u8 tmp;
402 tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
403 msleep(1);
404 tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 1);
405 msleep(1);
406 tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
407 msleep(1);
408
409 tas->acr &= ~TAS_ACR_ANALOG_PDOWN;
410 tas->acr |= TAS_ACR_B_MONAUREAL | TAS_ACR_B_MON_SEL_RIGHT;
411 if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
412 return -ENODEV;
413
414 tmp = TAS_MCS_SCLK64 | TAS_MCS_SPORT_MODE_I2S | TAS_MCS_SPORT_WL_24BIT;
415 if (tas_write_reg(tas, TAS_REG_MCS, 1, &tmp))
416 return -ENODEV;
417
418 tmp = 0;
419 if (tas_write_reg(tas, TAS_REG_MCS2, 1, &tmp))
420 return -ENODEV;
421
422 return 0;
423}
424
425/* we are controlled via i2c and assume that is always up
426 * If that wasn't the case, we'd have to suspend once
427 * our i2c device is suspended, and then take note of that! */
428static int tas_suspend(struct tas *tas)
429{
430 tas->acr |= TAS_ACR_ANALOG_PDOWN;
431 tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
432 return 0;
433}
434
435static int tas_resume(struct tas *tas)
436{
437 /* reset codec */
438 tas_reset_init(tas);
439 tas_set_volume(tas);
440 tas_set_mixer(tas);
441 return 0;
442}
443
444#ifdef CONFIG_PM
445static int _tas_suspend(struct codec_info_item *cii, pm_message_t state)
446{
447 return tas_suspend(cii->codec_data);
448}
449
450static int _tas_resume(struct codec_info_item *cii)
451{
452 return tas_resume(cii->codec_data);
453}
454#endif
455
456static struct codec_info tas_codec_info = {
457 .transfers = tas_transfers,
458 /* in theory, we can drive it at 512 too...
459 * but so far the framework doesn't allow
460 * for that and I don't see much point in it. */
461 .sysclock_factor = 256,
462 /* same here, could be 32 for just one 16 bit format */
463 .bus_factor = 64,
464 .owner = THIS_MODULE,
465 .usable = tas_usable,
466#ifdef CONFIG_PM
467 .suspend = _tas_suspend,
468 .resume = _tas_resume,
469#endif
470};
471
472static int tas_init_codec(struct aoa_codec *codec)
473{
474 struct tas *tas = codec_to_tas(codec);
475 int err;
476
477 if (!tas->codec.gpio || !tas->codec.gpio->methods) {
478 printk(KERN_ERR PFX "gpios not assigned!!\n");
479 return -EINVAL;
480 }
481
482 if (tas_reset_init(tas)) {
483 printk(KERN_ERR PFX "tas failed to initialise\n");
484 return -ENXIO;
485 }
486
487 if (tas->codec.soundbus_dev->attach_codec(tas->codec.soundbus_dev,
488 aoa_get_card(),
489 &tas_codec_info, tas)) {
490 printk(KERN_ERR PFX "error attaching tas to soundbus\n");
491 return -ENODEV;
492 }
493
494 if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, tas, &ops)) {
495 printk(KERN_ERR PFX "failed to create tas snd device!\n");
496 return -ENODEV;
497 }
498 err = aoa_snd_ctl_add(snd_ctl_new1(&volume_control, tas));
499 if (err)
500 goto error;
501
502 err = aoa_snd_ctl_add(snd_ctl_new1(&mute_control, tas));
503 if (err)
504 goto error;
505
506 err = aoa_snd_ctl_add(snd_ctl_new1(&pcm1_control, tas));
507 if (err)
508 goto error;
509
510 err = aoa_snd_ctl_add(snd_ctl_new1(&monitor_control, tas));
511 if (err)
512 goto error;
513
514 err = aoa_snd_ctl_add(snd_ctl_new1(&capture_source_control, tas));
515 if (err)
516 goto error;
517
518 return 0;
519 error:
520 tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas);
521 snd_device_free(aoa_get_card(), tas);
522 return err;
523}
524
525static void tas_exit_codec(struct aoa_codec *codec)
526{
527 struct tas *tas = codec_to_tas(codec);
528
529 if (!tas->codec.soundbus_dev)
530 return;
531 tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas);
532}
533
534
535static struct i2c_driver tas_driver;
536
537static int tas_create(struct i2c_adapter *adapter,
538 struct device_node *node,
539 int addr)
540{
541 struct tas *tas;
542
543 tas = kzalloc(sizeof(struct tas), GFP_KERNEL);
544
545 if (!tas)
546 return -ENOMEM;
547
548 tas->i2c.driver = &tas_driver;
549 tas->i2c.adapter = adapter;
550 tas->i2c.addr = addr;
551 strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1);
552
553 if (i2c_attach_client(&tas->i2c)) {
554 printk(KERN_ERR PFX "failed to attach to i2c\n");
555 goto fail;
556 }
557
558 strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN-1);
559 tas->codec.owner = THIS_MODULE;
560 tas->codec.init = tas_init_codec;
561 tas->codec.exit = tas_exit_codec;
562 tas->codec.node = of_node_get(node);
563
564 if (aoa_codec_register(&tas->codec)) {
565 goto detach;
566 }
567 printk(KERN_DEBUG "snd-aoa-codec-tas: created and attached tas instance\n");
568 return 0;
569 detach:
570 i2c_detach_client(&tas->i2c);
571 fail:
572 kfree(tas);
573 return -EINVAL;
574}
575
576static int tas_i2c_attach(struct i2c_adapter *adapter)
577{
578 struct device_node *busnode, *dev = NULL;
579 struct pmac_i2c_bus *bus;
580
581 bus = pmac_i2c_adapter_to_bus(adapter);
582 if (bus == NULL)
583 return -ENODEV;
584 busnode = pmac_i2c_get_bus_node(bus);
585
586 while ((dev = of_get_next_child(busnode, dev)) != NULL) {
587 if (device_is_compatible(dev, "tas3004")) {
588 u32 *addr;
589 printk(KERN_DEBUG PFX "found tas3004\n");
590 addr = (u32 *) get_property(dev, "reg", NULL);
591 if (!addr)
592 continue;
593 return tas_create(adapter, dev, ((*addr) >> 1) & 0x7f);
594 }
595 /* older machines have no 'codec' node with a 'compatible'
596 * property that says 'tas3004', they just have a 'deq'
597 * node without any such property... */
598 if (strcmp(dev->name, "deq") == 0) {
599 u32 *_addr, addr;
600 printk(KERN_DEBUG PFX "found 'deq' node\n");
601 _addr = (u32 *) get_property(dev, "i2c-address", NULL);
602 if (!_addr)
603 continue;
604 addr = ((*_addr) >> 1) & 0x7f;
605 /* now, if the address doesn't match any of the two
606 * that a tas3004 can have, we cannot handle this.
607 * I doubt it ever happens but hey. */
608 if (addr != 0x34 && addr != 0x35)
609 continue;
610 return tas_create(adapter, dev, addr);
611 }
612 }
613 return -ENODEV;
614}
615
616static int tas_i2c_detach(struct i2c_client *client)
617{
618 struct tas *tas = container_of(client, struct tas, i2c);
619 int err;
620 u8 tmp = TAS_ACR_ANALOG_PDOWN;
621
622 if ((err = i2c_detach_client(client)))
623 return err;
624 aoa_codec_unregister(&tas->codec);
625 of_node_put(tas->codec.node);
626
627 /* power down codec chip */
628 tas_write_reg(tas, TAS_REG_ACR, 1, &tmp);
629
630 kfree(tas);
631 return 0;
632}
633
634static struct i2c_driver tas_driver = {
635 .driver = {
636 .name = "aoa_codec_tas",
637 .owner = THIS_MODULE,
638 },
639 .attach_adapter = tas_i2c_attach,
640 .detach_client = tas_i2c_detach,
641};
642
643static int __init tas_init(void)
644{
645 return i2c_add_driver(&tas_driver);
646}
647
648static void __exit tas_exit(void)
649{
650 i2c_del_driver(&tas_driver);
651}
652
653module_init(tas_init);
654module_exit(tas_exit);
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.h b/sound/aoa/codecs/snd-aoa-codec-tas.h
new file mode 100644
index 000000000000..daf81f45d83a
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.h
@@ -0,0 +1,47 @@
1/*
2 * Apple Onboard Audio driver for tas codec (header)
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#ifndef __SND_AOA_CODECTASH
9#define __SND_AOA_CODECTASH
10
11#define TAS_REG_MCS 0x01 /* main control */
12# define TAS_MCS_FASTLOAD (1<<7)
13# define TAS_MCS_SCLK64 (1<<6)
14# define TAS_MCS_SPORT_MODE_MASK (3<<4)
15# define TAS_MCS_SPORT_MODE_I2S (2<<4)
16# define TAS_MCS_SPORT_MODE_RJ (1<<4)
17# define TAS_MCS_SPORT_MODE_LJ (0<<4)
18# define TAS_MCS_SPORT_WL_MASK (3<<0)
19# define TAS_MCS_SPORT_WL_16BIT (0<<0)
20# define TAS_MCS_SPORT_WL_18BIT (1<<0)
21# define TAS_MCS_SPORT_WL_20BIT (2<<0)
22# define TAS_MCS_SPORT_WL_24BIT (3<<0)
23
24#define TAS_REG_DRC 0x02
25#define TAS_REG_VOL 0x04
26#define TAS_REG_TREBLE 0x05
27#define TAS_REG_BASS 0x06
28#define TAS_REG_LMIX 0x07
29#define TAS_REG_RMIX 0x08
30
31#define TAS_REG_ACR 0x40 /* analog control */
32# define TAS_ACR_B_MONAUREAL (1<<7)
33# define TAS_ACR_B_MON_SEL_RIGHT (1<<6)
34# define TAS_ACR_DEEMPH_MASK (3<<2)
35# define TAS_ACR_DEEMPH_OFF (0<<2)
36# define TAS_ACR_DEEMPH_48KHz (1<<2)
37# define TAS_ACR_DEEMPH_44KHz (2<<2)
38# define TAS_ACR_INPUT_B (1<<1)
39# define TAS_ACR_ANALOG_PDOWN (1<<0)
40
41#define TAS_REG_MCS2 0x43 /* main control 2 */
42# define TAS_MCS2_ALLPASS (1<<1)
43
44#define TAS_REG_LEFT_BIQUAD6 0x10
45#define TAS_REG_RIGHT_BIQUAD6 0x19
46
47#endif /* __SND_AOA_CODECTASH */
diff --git a/sound/aoa/codecs/snd-aoa-codec-toonie.c b/sound/aoa/codecs/snd-aoa-codec-toonie.c
new file mode 100644
index 000000000000..bcc555647e79
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-toonie.c
@@ -0,0 +1,141 @@
1/*
2 * Apple Onboard Audio driver for Toonie codec
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 *
8 *
9 * This is a driver for the toonie codec chip. This chip is present
10 * on the Mac Mini and is nothing but a DAC.
11 */
12#include <linux/delay.h>
13#include <linux/module.h>
14MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
15MODULE_LICENSE("GPL");
16MODULE_DESCRIPTION("toonie codec driver for snd-aoa");
17
18#include "../aoa.h"
19#include "../soundbus/soundbus.h"
20
21
22#define PFX "snd-aoa-codec-toonie: "
23
24struct toonie {
25 struct aoa_codec codec;
26};
27#define codec_to_toonie(c) container_of(c, struct toonie, codec)
28
29static int toonie_dev_register(struct snd_device *dev)
30{
31 return 0;
32}
33
34static struct snd_device_ops ops = {
35 .dev_register = toonie_dev_register,
36};
37
38static struct transfer_info toonie_transfers[] = {
39 /* This thing *only* has analog output,
40 * the rates are taken from Info.plist
41 * from Darwin. */
42 {
43 .formats = SNDRV_PCM_FMTBIT_S16_BE |
44 SNDRV_PCM_FMTBIT_S24_BE,
45 .rates = SNDRV_PCM_RATE_32000 |
46 SNDRV_PCM_RATE_44100 |
47 SNDRV_PCM_RATE_48000 |
48 SNDRV_PCM_RATE_88200 |
49 SNDRV_PCM_RATE_96000,
50 },
51 {}
52};
53
54#ifdef CONFIG_PM
55static int toonie_suspend(struct codec_info_item *cii, pm_message_t state)
56{
57 /* can we turn it off somehow? */
58 return 0;
59}
60
61static int toonie_resume(struct codec_info_item *cii)
62{
63 return 0;
64}
65#endif /* CONFIG_PM */
66
67static struct codec_info toonie_codec_info = {
68 .transfers = toonie_transfers,
69 .sysclock_factor = 256,
70 .bus_factor = 64,
71 .owner = THIS_MODULE,
72#ifdef CONFIG_PM
73 .suspend = toonie_suspend,
74 .resume = toonie_resume,
75#endif
76};
77
78static int toonie_init_codec(struct aoa_codec *codec)
79{
80 struct toonie *toonie = codec_to_toonie(codec);
81
82 if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, toonie, &ops)) {
83 printk(KERN_ERR PFX "failed to create toonie snd device!\n");
84 return -ENODEV;
85 }
86
87 /* nothing connected? what a joke! */
88 if (toonie->codec.connected != 1)
89 return -ENOTCONN;
90
91 if (toonie->codec.soundbus_dev->attach_codec(toonie->codec.soundbus_dev,
92 aoa_get_card(),
93 &toonie_codec_info, toonie)) {
94 printk(KERN_ERR PFX "error creating toonie pcm\n");
95 return -ENODEV;
96 }
97
98 return 0;
99}
100
101static void toonie_exit_codec(struct aoa_codec *codec)
102{
103 struct toonie *toonie = codec_to_toonie(codec);
104
105 if (!toonie->codec.soundbus_dev) {
106 printk(KERN_ERR PFX "toonie_exit_codec called without soundbus_dev!\n");
107 return;
108 }
109 toonie->codec.soundbus_dev->detach_codec(toonie->codec.soundbus_dev, toonie);
110}
111
112static struct toonie *toonie;
113
114static int __init toonie_init(void)
115{
116 toonie = kzalloc(sizeof(struct toonie), GFP_KERNEL);
117
118 if (!toonie)
119 return -ENOMEM;
120
121 strlcpy(toonie->codec.name, "toonie", sizeof(toonie->codec.name));
122 toonie->codec.owner = THIS_MODULE;
123 toonie->codec.init = toonie_init_codec;
124 toonie->codec.exit = toonie_exit_codec;
125
126 if (aoa_codec_register(&toonie->codec)) {
127 kfree(toonie);
128 return -EINVAL;
129 }
130
131 return 0;
132}
133
134static void __exit toonie_exit(void)
135{
136 aoa_codec_unregister(&toonie->codec);
137 kfree(toonie);
138}
139
140module_init(toonie_init);
141module_exit(toonie_exit);
diff --git a/sound/aoa/core/Makefile b/sound/aoa/core/Makefile
new file mode 100644
index 000000000000..62dc7287f663
--- /dev/null
+++ b/sound/aoa/core/Makefile
@@ -0,0 +1,5 @@
1obj-$(CONFIG_SND_AOA) += snd-aoa.o
2snd-aoa-objs := snd-aoa-core.o \
3 snd-aoa-alsa.o \
4 snd-aoa-gpio-pmf.o \
5 snd-aoa-gpio-feature.o
diff --git a/sound/aoa/core/snd-aoa-alsa.c b/sound/aoa/core/snd-aoa-alsa.c
new file mode 100644
index 000000000000..b42fdea77ed0
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-alsa.c
@@ -0,0 +1,98 @@
1/*
2 * Apple Onboard Audio Alsa helpers
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#include <linux/module.h>
9#include "snd-aoa-alsa.h"
10
11static int index = -1;
12module_param(index, int, 0444);
13MODULE_PARM_DESC(index, "index for AOA sound card.");
14
15static struct aoa_card *aoa_card;
16
17int aoa_alsa_init(char *name, struct module *mod)
18{
19 struct snd_card *alsa_card;
20 int err;
21
22 if (aoa_card)
23 /* cannot be EEXIST due to usage in aoa_fabric_register */
24 return -EBUSY;
25
26 alsa_card = snd_card_new(index, name, mod, sizeof(struct aoa_card));
27 if (!alsa_card)
28 return -ENOMEM;
29 aoa_card = alsa_card->private_data;
30 aoa_card->alsa_card = alsa_card;
31 strlcpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
32 strlcpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
33 strlcpy(alsa_card->longname, name, sizeof(alsa_card->longname));
34 strlcpy(alsa_card->mixername, name, sizeof(alsa_card->mixername));
35 err = snd_card_register(aoa_card->alsa_card);
36 if (err < 0) {
37 printk(KERN_ERR "snd-aoa: couldn't register alsa card\n");
38 snd_card_free(aoa_card->alsa_card);
39 aoa_card = NULL;
40 return err;
41 }
42 return 0;
43}
44
45struct snd_card *aoa_get_card(void)
46{
47 if (aoa_card)
48 return aoa_card->alsa_card;
49 return NULL;
50}
51EXPORT_SYMBOL_GPL(aoa_get_card);
52
53void aoa_alsa_cleanup(void)
54{
55 if (aoa_card) {
56 snd_card_free(aoa_card->alsa_card);
57 aoa_card = NULL;
58 }
59}
60
61int aoa_snd_device_new(snd_device_type_t type,
62 void * device_data, struct snd_device_ops * ops)
63{
64 struct snd_card *card = aoa_get_card();
65 int err;
66
67 if (!card) return -ENOMEM;
68
69 err = snd_device_new(card, type, device_data, ops);
70 if (err) {
71 printk(KERN_ERR "snd-aoa: failed to create snd device (%d)\n", err);
72 return err;
73 }
74 err = snd_device_register(card, device_data);
75 if (err) {
76 printk(KERN_ERR "snd-aoa: failed to register "
77 "snd device (%d)\n", err);
78 printk(KERN_ERR "snd-aoa: have you forgotten the "
79 "dev_register callback?\n");
80 snd_device_free(card, device_data);
81 }
82 return err;
83}
84EXPORT_SYMBOL_GPL(aoa_snd_device_new);
85
86int aoa_snd_ctl_add(struct snd_kcontrol* control)
87{
88 int err;
89
90 if (!aoa_card) return -ENODEV;
91
92 err = snd_ctl_add(aoa_card->alsa_card, control);
93 if (err)
94 printk(KERN_ERR "snd-aoa: failed to add alsa control (%d)\n",
95 err);
96 return err;
97}
98EXPORT_SYMBOL_GPL(aoa_snd_ctl_add);
diff --git a/sound/aoa/core/snd-aoa-alsa.h b/sound/aoa/core/snd-aoa-alsa.h
new file mode 100644
index 000000000000..660d2f1793bb
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-alsa.h
@@ -0,0 +1,16 @@
1/*
2 * Apple Onboard Audio Alsa private helpers
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#ifndef __SND_AOA_ALSA_H
10#define __SND_AOA_ALSA_H
11#include "../aoa.h"
12
13extern int aoa_alsa_init(char *name, struct module *mod);
14extern void aoa_alsa_cleanup(void);
15
16#endif /* __SND_AOA_ALSA_H */
diff --git a/sound/aoa/core/snd-aoa-core.c b/sound/aoa/core/snd-aoa-core.c
new file mode 100644
index 000000000000..ecd2d8263f2d
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-core.c
@@ -0,0 +1,162 @@
1/*
2 * Apple Onboard Audio driver core
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/list.h>
12#include "../aoa.h"
13#include "snd-aoa-alsa.h"
14
15MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver");
16MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
17MODULE_LICENSE("GPL");
18
19/* We allow only one fabric. This simplifies things,
20 * and more don't really make that much sense */
21static struct aoa_fabric *fabric;
22static LIST_HEAD(codec_list);
23
24static int attach_codec_to_fabric(struct aoa_codec *c)
25{
26 int err;
27
28 if (!try_module_get(c->owner))
29 return -EBUSY;
30 /* found_codec has to be assigned */
31 err = -ENOENT;
32 if (fabric->found_codec)
33 err = fabric->found_codec(c);
34 if (err) {
35 module_put(c->owner);
36 printk(KERN_ERR "snd-aoa: fabric didn't like codec %s\n",
37 c->name);
38 return err;
39 }
40 c->fabric = fabric;
41
42 err = 0;
43 if (c->init)
44 err = c->init(c);
45 if (err) {
46 printk(KERN_ERR "snd-aoa: codec %s didn't init\n", c->name);
47 c->fabric = NULL;
48 if (fabric->remove_codec)
49 fabric->remove_codec(c);
50 module_put(c->owner);
51 return err;
52 }
53 if (fabric->attached_codec)
54 fabric->attached_codec(c);
55 return 0;
56}
57
58int aoa_codec_register(struct aoa_codec *codec)
59{
60 int err = 0;
61
62 /* if there's a fabric already, we can tell if we
63 * will want to have this codec, so propagate error
64 * through. Otherwise, this will happen later... */
65 if (fabric)
66 err = attach_codec_to_fabric(codec);
67 if (!err)
68 list_add(&codec->list, &codec_list);
69 return err;
70}
71EXPORT_SYMBOL_GPL(aoa_codec_register);
72
73void aoa_codec_unregister(struct aoa_codec *codec)
74{
75 list_del(&codec->list);
76 if (codec->fabric && codec->exit)
77 codec->exit(codec);
78 if (fabric && fabric->remove_codec)
79 fabric->remove_codec(codec);
80 codec->fabric = NULL;
81 module_put(codec->owner);
82}
83EXPORT_SYMBOL_GPL(aoa_codec_unregister);
84
85int aoa_fabric_register(struct aoa_fabric *new_fabric)
86{
87 struct aoa_codec *c;
88 int err;
89
90 /* allow querying for presence of fabric
91 * (i.e. do this test first!) */
92 if (new_fabric == fabric) {
93 err = -EALREADY;
94 goto attach;
95 }
96 if (fabric)
97 return -EEXIST;
98 if (!new_fabric)
99 return -EINVAL;
100
101 err = aoa_alsa_init(new_fabric->name, new_fabric->owner);
102 if (err)
103 return err;
104
105 fabric = new_fabric;
106
107 attach:
108 list_for_each_entry(c, &codec_list, list) {
109 if (c->fabric != fabric)
110 attach_codec_to_fabric(c);
111 }
112 return err;
113}
114EXPORT_SYMBOL_GPL(aoa_fabric_register);
115
116void aoa_fabric_unregister(struct aoa_fabric *old_fabric)
117{
118 struct aoa_codec *c;
119
120 if (fabric != old_fabric)
121 return;
122
123 list_for_each_entry(c, &codec_list, list) {
124 if (c->fabric)
125 aoa_fabric_unlink_codec(c);
126 }
127
128 aoa_alsa_cleanup();
129
130 fabric = NULL;
131}
132EXPORT_SYMBOL_GPL(aoa_fabric_unregister);
133
134void aoa_fabric_unlink_codec(struct aoa_codec *codec)
135{
136 if (!codec->fabric) {
137 printk(KERN_ERR "snd-aoa: fabric unassigned "
138 "in aoa_fabric_unlink_codec\n");
139 dump_stack();
140 return;
141 }
142 if (codec->exit)
143 codec->exit(codec);
144 if (codec->fabric->remove_codec)
145 codec->fabric->remove_codec(codec);
146 codec->fabric = NULL;
147 module_put(codec->owner);
148}
149EXPORT_SYMBOL_GPL(aoa_fabric_unlink_codec);
150
151static int __init aoa_init(void)
152{
153 return 0;
154}
155
156static void __exit aoa_exit(void)
157{
158 aoa_alsa_cleanup();
159}
160
161module_init(aoa_init);
162module_exit(aoa_exit);
diff --git a/sound/aoa/core/snd-aoa-gpio-feature.c b/sound/aoa/core/snd-aoa-gpio-feature.c
new file mode 100644
index 000000000000..2c6eb7784cc9
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-gpio-feature.c
@@ -0,0 +1,399 @@
1/*
2 * Apple Onboard Audio feature call GPIO control
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 *
8 * This file contains the GPIO control routines for
9 * direct (through feature calls) access to the GPIO
10 * registers.
11 */
12
13#include <asm/pmac_feature.h>
14#include <linux/interrupt.h>
15#include "../aoa.h"
16
17/* TODO: these are 20 global variables
18 * that aren't used on most machines...
19 * Move them into a dynamically allocated
20 * structure and use that.
21 */
22
23/* these are the GPIO numbers (register addresses as offsets into
24 * the GPIO space) */
25static int headphone_mute_gpio;
26static int amp_mute_gpio;
27static int lineout_mute_gpio;
28static int hw_reset_gpio;
29static int lineout_detect_gpio;
30static int headphone_detect_gpio;
31static int linein_detect_gpio;
32
33/* see the SWITCH_GPIO macro */
34static int headphone_mute_gpio_activestate;
35static int amp_mute_gpio_activestate;
36static int lineout_mute_gpio_activestate;
37static int hw_reset_gpio_activestate;
38static int lineout_detect_gpio_activestate;
39static int headphone_detect_gpio_activestate;
40static int linein_detect_gpio_activestate;
41
42/* node pointers that we save when getting the GPIO number
43 * to get the interrupt later */
44static struct device_node *lineout_detect_node;
45static struct device_node *linein_detect_node;
46static struct device_node *headphone_detect_node;
47
48static int lineout_detect_irq;
49static int linein_detect_irq;
50static int headphone_detect_irq;
51
52static struct device_node *get_gpio(char *name,
53 char *altname,
54 int *gpioptr,
55 int *gpioactiveptr)
56{
57 struct device_node *np, *gpio;
58 u32 *reg;
59 char *audio_gpio;
60
61 *gpioptr = -1;
62
63 /* check if we can get it the easy way ... */
64 np = of_find_node_by_name(NULL, name);
65 if (!np) {
66 /* some machines have only gpioX/extint-gpioX nodes,
67 * and an audio-gpio property saying what it is ...
68 * So what we have to do is enumerate all children
69 * of the gpio node and check them all. */
70 gpio = of_find_node_by_name(NULL, "gpio");
71 if (!gpio)
72 return NULL;
73 while ((np = of_get_next_child(gpio, np))) {
74 audio_gpio = get_property(np, "audio-gpio", NULL);
75 if (!audio_gpio)
76 continue;
77 if (strcmp(audio_gpio, name) == 0)
78 break;
79 if (altname && (strcmp(audio_gpio, altname) == 0))
80 break;
81 }
82 /* still not found, assume not there */
83 if (!np)
84 return NULL;
85 }
86
87 reg = (u32 *)get_property(np, "reg", NULL);
88 if (!reg)
89 return NULL;
90
91 *gpioptr = *reg;
92
93 /* this is a hack, usually the GPIOs 'reg' property
94 * should have the offset based from the GPIO space
95 * which is at 0x50, but apparently not always... */
96 if (*gpioptr < 0x50)
97 *gpioptr += 0x50;
98
99 reg = (u32 *)get_property(np, "audio-gpio-active-state", NULL);
100 if (!reg)
101 /* Apple seems to default to 1, but
102 * that doesn't seem right at least on most
103 * machines. So until proven that the opposite
104 * is necessary, we default to 0
105 * (which, incidentally, snd-powermac also does...) */
106 *gpioactiveptr = 0;
107 else
108 *gpioactiveptr = *reg;
109
110 return np;
111}
112
113static void get_irq(struct device_node * np, int *irqptr)
114{
115 *irqptr = -1;
116 if (!np)
117 return;
118 if (np->n_intrs != 1)
119 return;
120 *irqptr = np->intrs[0].line;
121}
122
123/* 0x4 is outenable, 0x1 is out, thus 4 or 5 */
124#define SWITCH_GPIO(name, v, on) \
125 (((v)&~1) | ((on)? \
126 (name##_gpio_activestate==0?4:5): \
127 (name##_gpio_activestate==0?5:4)))
128
129#define FTR_GPIO(name, bit) \
130static void ftr_gpio_set_##name(struct gpio_runtime *rt, int on)\
131{ \
132 int v; \
133 \
134 if (unlikely(!rt)) return; \
135 \
136 if (name##_mute_gpio < 0) \
137 return; \
138 \
139 v = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, \
140 name##_mute_gpio, \
141 0); \
142 \
143 /* muted = !on... */ \
144 v = SWITCH_GPIO(name##_mute, v, !on); \
145 \
146 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, \
147 name##_mute_gpio, v); \
148 \
149 rt->implementation_private &= ~(1<<bit); \
150 rt->implementation_private |= (!!on << bit); \
151} \
152static int ftr_gpio_get_##name(struct gpio_runtime *rt) \
153{ \
154 if (unlikely(!rt)) return 0; \
155 return (rt->implementation_private>>bit)&1; \
156}
157
158FTR_GPIO(headphone, 0);
159FTR_GPIO(amp, 1);
160FTR_GPIO(lineout, 2);
161
162static void ftr_gpio_set_hw_reset(struct gpio_runtime *rt, int on)
163{
164 int v;
165
166 if (unlikely(!rt)) return;
167 if (hw_reset_gpio < 0)
168 return;
169
170 v = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL,
171 hw_reset_gpio, 0);
172 v = SWITCH_GPIO(hw_reset, v, on);
173 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL,
174 hw_reset_gpio, v);
175}
176
177static void ftr_gpio_all_amps_off(struct gpio_runtime *rt)
178{
179 int saved;
180
181 if (unlikely(!rt)) return;
182 saved = rt->implementation_private;
183 ftr_gpio_set_headphone(rt, 0);
184 ftr_gpio_set_amp(rt, 0);
185 ftr_gpio_set_lineout(rt, 0);
186 rt->implementation_private = saved;
187}
188
189static void ftr_gpio_all_amps_restore(struct gpio_runtime *rt)
190{
191 int s;
192
193 if (unlikely(!rt)) return;
194 s = rt->implementation_private;
195 ftr_gpio_set_headphone(rt, (s>>0)&1);
196 ftr_gpio_set_amp(rt, (s>>1)&1);
197 ftr_gpio_set_lineout(rt, (s>>2)&1);
198}
199
200static void ftr_handle_notify(void *data)
201{
202 struct gpio_notification *notif = data;
203
204 mutex_lock(&notif->mutex);
205 if (notif->notify)
206 notif->notify(notif->data);
207 mutex_unlock(&notif->mutex);
208}
209
210static void ftr_gpio_init(struct gpio_runtime *rt)
211{
212 get_gpio("headphone-mute", NULL,
213 &headphone_mute_gpio,
214 &headphone_mute_gpio_activestate);
215 get_gpio("amp-mute", NULL,
216 &amp_mute_gpio,
217 &amp_mute_gpio_activestate);
218 get_gpio("lineout-mute", NULL,
219 &lineout_mute_gpio,
220 &lineout_mute_gpio_activestate);
221 get_gpio("hw-reset", "audio-hw-reset",
222 &hw_reset_gpio,
223 &hw_reset_gpio_activestate);
224
225 headphone_detect_node = get_gpio("headphone-detect", NULL,
226 &headphone_detect_gpio,
227 &headphone_detect_gpio_activestate);
228 /* go Apple, and thanks for giving these different names
229 * across the board... */
230 lineout_detect_node = get_gpio("lineout-detect", "line-output-detect",
231 &lineout_detect_gpio,
232 &lineout_detect_gpio_activestate);
233 linein_detect_node = get_gpio("linein-detect", "line-input-detect",
234 &linein_detect_gpio,
235 &linein_detect_gpio_activestate);
236
237 get_irq(headphone_detect_node, &headphone_detect_irq);
238 get_irq(lineout_detect_node, &lineout_detect_irq);
239 get_irq(linein_detect_node, &linein_detect_irq);
240
241 ftr_gpio_all_amps_off(rt);
242 rt->implementation_private = 0;
243 INIT_WORK(&rt->headphone_notify.work, ftr_handle_notify,
244 &rt->headphone_notify);
245 INIT_WORK(&rt->line_in_notify.work, ftr_handle_notify,
246 &rt->line_in_notify);
247 INIT_WORK(&rt->line_out_notify.work, ftr_handle_notify,
248 &rt->line_out_notify);
249 mutex_init(&rt->headphone_notify.mutex);
250 mutex_init(&rt->line_in_notify.mutex);
251 mutex_init(&rt->line_out_notify.mutex);
252}
253
254static void ftr_gpio_exit(struct gpio_runtime *rt)
255{
256 ftr_gpio_all_amps_off(rt);
257 rt->implementation_private = 0;
258 if (rt->headphone_notify.notify)
259 free_irq(headphone_detect_irq, &rt->headphone_notify);
260 if (rt->line_in_notify.gpio_private)
261 free_irq(linein_detect_irq, &rt->line_in_notify);
262 if (rt->line_out_notify.gpio_private)
263 free_irq(lineout_detect_irq, &rt->line_out_notify);
264 cancel_delayed_work(&rt->headphone_notify.work);
265 cancel_delayed_work(&rt->line_in_notify.work);
266 cancel_delayed_work(&rt->line_out_notify.work);
267 flush_scheduled_work();
268 mutex_destroy(&rt->headphone_notify.mutex);
269 mutex_destroy(&rt->line_in_notify.mutex);
270 mutex_destroy(&rt->line_out_notify.mutex);
271}
272
273static irqreturn_t ftr_handle_notify_irq(int xx,
274 void *data,
275 struct pt_regs *regs)
276{
277 struct gpio_notification *notif = data;
278
279 schedule_work(&notif->work);
280
281 return IRQ_HANDLED;
282}
283
284static int ftr_set_notify(struct gpio_runtime *rt,
285 enum notify_type type,
286 notify_func_t notify,
287 void *data)
288{
289 struct gpio_notification *notif;
290 notify_func_t old;
291 int irq;
292 char *name;
293 int err = -EBUSY;
294
295 switch (type) {
296 case AOA_NOTIFY_HEADPHONE:
297 notif = &rt->headphone_notify;
298 name = "headphone-detect";
299 irq = headphone_detect_irq;
300 break;
301 case AOA_NOTIFY_LINE_IN:
302 notif = &rt->line_in_notify;
303 name = "linein-detect";
304 irq = linein_detect_irq;
305 break;
306 case AOA_NOTIFY_LINE_OUT:
307 notif = &rt->line_out_notify;
308 name = "lineout-detect";
309 irq = lineout_detect_irq;
310 break;
311 default:
312 return -EINVAL;
313 }
314
315 if (irq == -1)
316 return -ENODEV;
317
318 mutex_lock(&notif->mutex);
319
320 old = notif->notify;
321
322 if (!old && !notify) {
323 err = 0;
324 goto out_unlock;
325 }
326
327 if (old && notify) {
328 if (old == notify && notif->data == data)
329 err = 0;
330 goto out_unlock;
331 }
332
333 if (old && !notify)
334 free_irq(irq, notif);
335
336 if (!old && notify) {
337 err = request_irq(irq, ftr_handle_notify_irq, 0, name, notif);
338 if (err)
339 goto out_unlock;
340 }
341
342 notif->notify = notify;
343 notif->data = data;
344
345 err = 0;
346 out_unlock:
347 mutex_unlock(&notif->mutex);
348 return err;
349}
350
351static int ftr_get_detect(struct gpio_runtime *rt,
352 enum notify_type type)
353{
354 int gpio, ret, active;
355
356 switch (type) {
357 case AOA_NOTIFY_HEADPHONE:
358 gpio = headphone_detect_gpio;
359 active = headphone_detect_gpio_activestate;
360 break;
361 case AOA_NOTIFY_LINE_IN:
362 gpio = linein_detect_gpio;
363 active = linein_detect_gpio_activestate;
364 break;
365 case AOA_NOTIFY_LINE_OUT:
366 gpio = lineout_detect_gpio;
367 active = lineout_detect_gpio_activestate;
368 break;
369 default:
370 return -EINVAL;
371 }
372
373 if (gpio == -1)
374 return -ENODEV;
375
376 ret = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio, 0);
377 if (ret < 0)
378 return ret;
379 return ((ret >> 1) & 1) == active;
380}
381
382static struct gpio_methods methods = {
383 .init = ftr_gpio_init,
384 .exit = ftr_gpio_exit,
385 .all_amps_off = ftr_gpio_all_amps_off,
386 .all_amps_restore = ftr_gpio_all_amps_restore,
387 .set_headphone = ftr_gpio_set_headphone,
388 .set_speakers = ftr_gpio_set_amp,
389 .set_lineout = ftr_gpio_set_lineout,
390 .set_hw_reset = ftr_gpio_set_hw_reset,
391 .get_headphone = ftr_gpio_get_headphone,
392 .get_speakers = ftr_gpio_get_amp,
393 .get_lineout = ftr_gpio_get_lineout,
394 .set_notify = ftr_set_notify,
395 .get_detect = ftr_get_detect,
396};
397
398struct gpio_methods *ftr_gpio_methods = &methods;
399EXPORT_SYMBOL_GPL(ftr_gpio_methods);
diff --git a/sound/aoa/core/snd-aoa-gpio-pmf.c b/sound/aoa/core/snd-aoa-gpio-pmf.c
new file mode 100644
index 000000000000..0e9b9bb2a6de
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-gpio-pmf.c
@@ -0,0 +1,246 @@
1/*
2 * Apple Onboard Audio pmf GPIOs
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#include <asm/pmac_feature.h>
10#include <asm/pmac_pfunc.h>
11#include "../aoa.h"
12
13#define PMF_GPIO(name, bit) \
14static void pmf_gpio_set_##name(struct gpio_runtime *rt, int on)\
15{ \
16 struct pmf_args args = { .count = 1, .u[0].v = !on }; \
17 \
18 if (unlikely(!rt)) return; \
19 pmf_call_function(rt->node, #name "-mute", &args); \
20 rt->implementation_private &= ~(1<<bit); \
21 rt->implementation_private |= (!!on << bit); \
22} \
23static int pmf_gpio_get_##name(struct gpio_runtime *rt) \
24{ \
25 if (unlikely(!rt)) return 0; \
26 return (rt->implementation_private>>bit)&1; \
27}
28
29PMF_GPIO(headphone, 0);
30PMF_GPIO(amp, 1);
31PMF_GPIO(lineout, 2);
32
33static void pmf_gpio_set_hw_reset(struct gpio_runtime *rt, int on)
34{
35 struct pmf_args args = { .count = 1, .u[0].v = !!on };
36
37 if (unlikely(!rt)) return;
38 pmf_call_function(rt->node, "hw-reset", &args);
39}
40
41static void pmf_gpio_all_amps_off(struct gpio_runtime *rt)
42{
43 int saved;
44
45 if (unlikely(!rt)) return;
46 saved = rt->implementation_private;
47 pmf_gpio_set_headphone(rt, 0);
48 pmf_gpio_set_amp(rt, 0);
49 pmf_gpio_set_lineout(rt, 0);
50 rt->implementation_private = saved;
51}
52
53static void pmf_gpio_all_amps_restore(struct gpio_runtime *rt)
54{
55 int s;
56
57 if (unlikely(!rt)) return;
58 s = rt->implementation_private;
59 pmf_gpio_set_headphone(rt, (s>>0)&1);
60 pmf_gpio_set_amp(rt, (s>>1)&1);
61 pmf_gpio_set_lineout(rt, (s>>2)&1);
62}
63
64static void pmf_handle_notify(void *data)
65{
66 struct gpio_notification *notif = data;
67
68 mutex_lock(&notif->mutex);
69 if (notif->notify)
70 notif->notify(notif->data);
71 mutex_unlock(&notif->mutex);
72}
73
74static void pmf_gpio_init(struct gpio_runtime *rt)
75{
76 pmf_gpio_all_amps_off(rt);
77 rt->implementation_private = 0;
78 INIT_WORK(&rt->headphone_notify.work, pmf_handle_notify,
79 &rt->headphone_notify);
80 INIT_WORK(&rt->line_in_notify.work, pmf_handle_notify,
81 &rt->line_in_notify);
82 INIT_WORK(&rt->line_out_notify.work, pmf_handle_notify,
83 &rt->line_out_notify);
84 mutex_init(&rt->headphone_notify.mutex);
85 mutex_init(&rt->line_in_notify.mutex);
86 mutex_init(&rt->line_out_notify.mutex);
87}
88
89static void pmf_gpio_exit(struct gpio_runtime *rt)
90{
91 pmf_gpio_all_amps_off(rt);
92 rt->implementation_private = 0;
93
94 if (rt->headphone_notify.gpio_private)
95 pmf_unregister_irq_client(rt->headphone_notify.gpio_private);
96 if (rt->line_in_notify.gpio_private)
97 pmf_unregister_irq_client(rt->line_in_notify.gpio_private);
98 if (rt->line_out_notify.gpio_private)
99 pmf_unregister_irq_client(rt->line_out_notify.gpio_private);
100
101 /* make sure no work is pending before freeing
102 * all things */
103 cancel_delayed_work(&rt->headphone_notify.work);
104 cancel_delayed_work(&rt->line_in_notify.work);
105 cancel_delayed_work(&rt->line_out_notify.work);
106 flush_scheduled_work();
107
108 mutex_destroy(&rt->headphone_notify.mutex);
109 mutex_destroy(&rt->line_in_notify.mutex);
110 mutex_destroy(&rt->line_out_notify.mutex);
111
112 if (rt->headphone_notify.gpio_private)
113 kfree(rt->headphone_notify.gpio_private);
114 if (rt->line_in_notify.gpio_private)
115 kfree(rt->line_in_notify.gpio_private);
116 if (rt->line_out_notify.gpio_private)
117 kfree(rt->line_out_notify.gpio_private);
118}
119
120static void pmf_handle_notify_irq(void *data)
121{
122 struct gpio_notification *notif = data;
123
124 schedule_work(&notif->work);
125}
126
127static int pmf_set_notify(struct gpio_runtime *rt,
128 enum notify_type type,
129 notify_func_t notify,
130 void *data)
131{
132 struct gpio_notification *notif;
133 notify_func_t old;
134 struct pmf_irq_client *irq_client;
135 char *name;
136 int err = -EBUSY;
137
138 switch (type) {
139 case AOA_NOTIFY_HEADPHONE:
140 notif = &rt->headphone_notify;
141 name = "headphone-detect";
142 break;
143 case AOA_NOTIFY_LINE_IN:
144 notif = &rt->line_in_notify;
145 name = "linein-detect";
146 break;
147 case AOA_NOTIFY_LINE_OUT:
148 notif = &rt->line_out_notify;
149 name = "lineout-detect";
150 break;
151 default:
152 return -EINVAL;
153 }
154
155 mutex_lock(&notif->mutex);
156
157 old = notif->notify;
158
159 if (!old && !notify) {
160 err = 0;
161 goto out_unlock;
162 }
163
164 if (old && notify) {
165 if (old == notify && notif->data == data)
166 err = 0;
167 goto out_unlock;
168 }
169
170 if (old && !notify) {
171 irq_client = notif->gpio_private;
172 pmf_unregister_irq_client(irq_client);
173 kfree(irq_client);
174 notif->gpio_private = NULL;
175 }
176 if (!old && notify) {
177 irq_client = kzalloc(sizeof(struct pmf_irq_client),
178 GFP_KERNEL);
179 irq_client->data = notif;
180 irq_client->handler = pmf_handle_notify_irq;
181 irq_client->owner = THIS_MODULE;
182 err = pmf_register_irq_client(rt->node,
183 name,
184 irq_client);
185 if (err) {
186 printk(KERN_ERR "snd-aoa: gpio layer failed to"
187 " register %s irq (%d)\n", name, err);
188 kfree(irq_client);
189 goto out_unlock;
190 }
191 notif->gpio_private = irq_client;
192 }
193 notif->notify = notify;
194 notif->data = data;
195
196 err = 0;
197 out_unlock:
198 mutex_unlock(&notif->mutex);
199 return err;
200}
201
202static int pmf_get_detect(struct gpio_runtime *rt,
203 enum notify_type type)
204{
205 char *name;
206 int err = -EBUSY, ret;
207 struct pmf_args args = { .count = 1, .u[0].p = &ret };
208
209 switch (type) {
210 case AOA_NOTIFY_HEADPHONE:
211 name = "headphone-detect";
212 break;
213 case AOA_NOTIFY_LINE_IN:
214 name = "linein-detect";
215 break;
216 case AOA_NOTIFY_LINE_OUT:
217 name = "lineout-detect";
218 break;
219 default:
220 return -EINVAL;
221 }
222
223 err = pmf_call_function(rt->node, name, &args);
224 if (err)
225 return err;
226 return ret;
227}
228
229static struct gpio_methods methods = {
230 .init = pmf_gpio_init,
231 .exit = pmf_gpio_exit,
232 .all_amps_off = pmf_gpio_all_amps_off,
233 .all_amps_restore = pmf_gpio_all_amps_restore,
234 .set_headphone = pmf_gpio_set_headphone,
235 .set_speakers = pmf_gpio_set_amp,
236 .set_lineout = pmf_gpio_set_lineout,
237 .set_hw_reset = pmf_gpio_set_hw_reset,
238 .get_headphone = pmf_gpio_get_headphone,
239 .get_speakers = pmf_gpio_get_amp,
240 .get_lineout = pmf_gpio_get_lineout,
241 .set_notify = pmf_set_notify,
242 .get_detect = pmf_get_detect,
243};
244
245struct gpio_methods *pmf_gpio_methods = &methods;
246EXPORT_SYMBOL_GPL(pmf_gpio_methods);
diff --git a/sound/aoa/fabrics/Kconfig b/sound/aoa/fabrics/Kconfig
new file mode 100644
index 000000000000..c3bc7705c86a
--- /dev/null
+++ b/sound/aoa/fabrics/Kconfig
@@ -0,0 +1,12 @@
1config SND_AOA_FABRIC_LAYOUT
2 tristate "layout-id fabric"
3 depends SND_AOA
4 select SND_AOA_SOUNDBUS
5 select SND_AOA_SOUNDBUS_I2S
6 ---help---
7 This enables the layout-id fabric for the Apple Onboard
8 Audio driver, the module holding it all together
9 based on the device-tree's layout-id property.
10
11 If you are unsure and have a later Apple machine,
12 compile it as a module.
diff --git a/sound/aoa/fabrics/Makefile b/sound/aoa/fabrics/Makefile
new file mode 100644
index 000000000000..55fc5e7e52cf
--- /dev/null
+++ b/sound/aoa/fabrics/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_SND_AOA_FABRIC_LAYOUT) += snd-aoa-fabric-layout.o
diff --git a/sound/aoa/fabrics/snd-aoa-fabric-layout.c b/sound/aoa/fabrics/snd-aoa-fabric-layout.c
new file mode 100644
index 000000000000..04a7238e9494
--- /dev/null
+++ b/sound/aoa/fabrics/snd-aoa-fabric-layout.c
@@ -0,0 +1,1109 @@
1/*
2 * Apple Onboard Audio driver -- layout fabric
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 *
8 *
9 * This fabric module looks for sound codecs
10 * based on the layout-id property in the device tree.
11 *
12 */
13
14#include <asm/prom.h>
15#include <linux/list.h>
16#include <linux/module.h>
17#include "../aoa.h"
18#include "../soundbus/soundbus.h"
19
20MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
21MODULE_LICENSE("GPL");
22MODULE_DESCRIPTION("Layout-ID fabric for snd-aoa");
23
24#define MAX_CODECS_PER_BUS 2
25
26/* These are the connections the layout fabric
27 * knows about. It doesn't really care about the
28 * input ones, but I thought I'd separate them
29 * to give them proper names. The thing is that
30 * Apple usually will distinguish the active output
31 * by GPIOs, while the active input is set directly
32 * on the codec. Hence we here tell the codec what
33 * we think is connected. This information is hard-
34 * coded below ... */
35#define CC_SPEAKERS (1<<0)
36#define CC_HEADPHONE (1<<1)
37#define CC_LINEOUT (1<<2)
38#define CC_DIGITALOUT (1<<3)
39#define CC_LINEIN (1<<4)
40#define CC_MICROPHONE (1<<5)
41#define CC_DIGITALIN (1<<6)
42/* pretty bogus but users complain...
43 * This is a flag saying that the LINEOUT
44 * should be renamed to HEADPHONE.
45 * be careful with input detection! */
46#define CC_LINEOUT_LABELLED_HEADPHONE (1<<7)
47
48struct codec_connection {
49 /* CC_ flags from above */
50 int connected;
51 /* codec dependent bit to be set in the aoa_codec.connected field.
52 * This intentionally doesn't have any generic flags because the
53 * fabric has to know the codec anyway and all codecs might have
54 * different connectors */
55 int codec_bit;
56};
57
58struct codec_connect_info {
59 char *name;
60 struct codec_connection *connections;
61};
62
63#define LAYOUT_FLAG_COMBO_LINEOUT_SPDIF (1<<0)
64
65struct layout {
66 unsigned int layout_id;
67 struct codec_connect_info codecs[MAX_CODECS_PER_BUS];
68 int flags;
69
70 /* if busname is not assigned, we use 'Master' below,
71 * so that our layout table doesn't need to be filled
72 * too much.
73 * We only assign these two if we expect to find more
74 * than one soundbus, i.e. on those machines with
75 * multiple layout-ids */
76 char *busname;
77 int pcmid;
78};
79
80MODULE_ALIAS("sound-layout-41");
81MODULE_ALIAS("sound-layout-45");
82MODULE_ALIAS("sound-layout-51");
83MODULE_ALIAS("sound-layout-58");
84MODULE_ALIAS("sound-layout-60");
85MODULE_ALIAS("sound-layout-61");
86MODULE_ALIAS("sound-layout-64");
87MODULE_ALIAS("sound-layout-65");
88MODULE_ALIAS("sound-layout-68");
89MODULE_ALIAS("sound-layout-69");
90MODULE_ALIAS("sound-layout-70");
91MODULE_ALIAS("sound-layout-72");
92MODULE_ALIAS("sound-layout-80");
93MODULE_ALIAS("sound-layout-82");
94MODULE_ALIAS("sound-layout-84");
95MODULE_ALIAS("sound-layout-86");
96MODULE_ALIAS("sound-layout-92");
97
98/* onyx with all but microphone connected */
99static struct codec_connection onyx_connections_nomic[] = {
100 {
101 .connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
102 .codec_bit = 0,
103 },
104 {
105 .connected = CC_DIGITALOUT,
106 .codec_bit = 1,
107 },
108 {
109 .connected = CC_LINEIN,
110 .codec_bit = 2,
111 },
112 {} /* terminate array by .connected == 0 */
113};
114
115/* onyx on machines without headphone */
116static struct codec_connection onyx_connections_noheadphones[] = {
117 {
118 .connected = CC_SPEAKERS | CC_LINEOUT |
119 CC_LINEOUT_LABELLED_HEADPHONE,
120 .codec_bit = 0,
121 },
122 {
123 .connected = CC_DIGITALOUT,
124 .codec_bit = 1,
125 },
126 /* FIXME: are these correct? probably not for all the machines
127 * below ... If not this will need separating. */
128 {
129 .connected = CC_LINEIN,
130 .codec_bit = 2,
131 },
132 {
133 .connected = CC_MICROPHONE,
134 .codec_bit = 3,
135 },
136 {} /* terminate array by .connected == 0 */
137};
138
139/* onyx on machines with real line-out */
140static struct codec_connection onyx_connections_reallineout[] = {
141 {
142 .connected = CC_SPEAKERS | CC_LINEOUT | CC_HEADPHONE,
143 .codec_bit = 0,
144 },
145 {
146 .connected = CC_DIGITALOUT,
147 .codec_bit = 1,
148 },
149 {
150 .connected = CC_LINEIN,
151 .codec_bit = 2,
152 },
153 {} /* terminate array by .connected == 0 */
154};
155
156/* tas on machines without line out */
157static struct codec_connection tas_connections_nolineout[] = {
158 {
159 .connected = CC_SPEAKERS | CC_HEADPHONE,
160 .codec_bit = 0,
161 },
162 {
163 .connected = CC_LINEIN,
164 .codec_bit = 2,
165 },
166 {
167 .connected = CC_MICROPHONE,
168 .codec_bit = 3,
169 },
170 {} /* terminate array by .connected == 0 */
171};
172
173/* tas on machines with neither line out nor line in */
174static struct codec_connection tas_connections_noline[] = {
175 {
176 .connected = CC_SPEAKERS | CC_HEADPHONE,
177 .codec_bit = 0,
178 },
179 {
180 .connected = CC_MICROPHONE,
181 .codec_bit = 3,
182 },
183 {} /* terminate array by .connected == 0 */
184};
185
186/* tas on machines without microphone */
187static struct codec_connection tas_connections_nomic[] = {
188 {
189 .connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
190 .codec_bit = 0,
191 },
192 {
193 .connected = CC_LINEIN,
194 .codec_bit = 2,
195 },
196 {} /* terminate array by .connected == 0 */
197};
198
199/* tas on machines with everything connected */
200static struct codec_connection tas_connections_all[] = {
201 {
202 .connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
203 .codec_bit = 0,
204 },
205 {
206 .connected = CC_LINEIN,
207 .codec_bit = 2,
208 },
209 {
210 .connected = CC_MICROPHONE,
211 .codec_bit = 3,
212 },
213 {} /* terminate array by .connected == 0 */
214};
215
216static struct codec_connection toonie_connections[] = {
217 {
218 .connected = CC_SPEAKERS | CC_HEADPHONE,
219 .codec_bit = 0,
220 },
221 {} /* terminate array by .connected == 0 */
222};
223
224static struct codec_connection topaz_input[] = {
225 {
226 .connected = CC_DIGITALIN,
227 .codec_bit = 0,
228 },
229 {} /* terminate array by .connected == 0 */
230};
231
232static struct codec_connection topaz_output[] = {
233 {
234 .connected = CC_DIGITALOUT,
235 .codec_bit = 1,
236 },
237 {} /* terminate array by .connected == 0 */
238};
239
240static struct codec_connection topaz_inout[] = {
241 {
242 .connected = CC_DIGITALIN,
243 .codec_bit = 0,
244 },
245 {
246 .connected = CC_DIGITALOUT,
247 .codec_bit = 1,
248 },
249 {} /* terminate array by .connected == 0 */
250};
251
252static struct layout layouts[] = {
253 /* last PowerBooks (15" Oct 2005) */
254 { .layout_id = 82,
255 .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
256 .codecs[0] = {
257 .name = "onyx",
258 .connections = onyx_connections_noheadphones,
259 },
260 .codecs[1] = {
261 .name = "topaz",
262 .connections = topaz_input,
263 },
264 },
265 /* PowerMac9,1 */
266 { .layout_id = 60,
267 .codecs[0] = {
268 .name = "onyx",
269 .connections = onyx_connections_reallineout,
270 },
271 },
272 /* PowerMac9,1 */
273 { .layout_id = 61,
274 .codecs[0] = {
275 .name = "topaz",
276 .connections = topaz_input,
277 },
278 },
279 /* PowerBook5,7 */
280 { .layout_id = 64,
281 .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
282 .codecs[0] = {
283 .name = "onyx",
284 .connections = onyx_connections_noheadphones,
285 },
286 },
287 /* PowerBook5,7 */
288 { .layout_id = 65,
289 .codecs[0] = {
290 .name = "topaz",
291 .connections = topaz_input,
292 },
293 },
294 /* PowerBook5,9 [17" Oct 2005] */
295 { .layout_id = 84,
296 .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
297 .codecs[0] = {
298 .name = "onyx",
299 .connections = onyx_connections_noheadphones,
300 },
301 .codecs[1] = {
302 .name = "topaz",
303 .connections = topaz_input,
304 },
305 },
306 /* PowerMac8,1 */
307 { .layout_id = 45,
308 .codecs[0] = {
309 .name = "onyx",
310 .connections = onyx_connections_noheadphones,
311 },
312 .codecs[1] = {
313 .name = "topaz",
314 .connections = topaz_input,
315 },
316 },
317 /* Quad PowerMac (analog in, analog/digital out) */
318 { .layout_id = 68,
319 .codecs[0] = {
320 .name = "onyx",
321 .connections = onyx_connections_nomic,
322 },
323 },
324 /* Quad PowerMac (digital in) */
325 { .layout_id = 69,
326 .codecs[0] = {
327 .name = "topaz",
328 .connections = topaz_input,
329 },
330 .busname = "digital in", .pcmid = 1 },
331 /* Early 2005 PowerBook (PowerBook 5,6) */
332 { .layout_id = 70,
333 .codecs[0] = {
334 .name = "tas",
335 .connections = tas_connections_nolineout,
336 },
337 },
338 /* PowerBook 5,4 */
339 { .layout_id = 51,
340 .codecs[0] = {
341 .name = "tas",
342 .connections = tas_connections_nolineout,
343 },
344 },
345 /* PowerBook6,7 */
346 { .layout_id = 80,
347 .codecs[0] = {
348 .name = "tas",
349 .connections = tas_connections_noline,
350 },
351 },
352 /* PowerBook6,8 */
353 { .layout_id = 72,
354 .codecs[0] = {
355 .name = "tas",
356 .connections = tas_connections_nolineout,
357 },
358 },
359 /* PowerMac8,2 */
360 { .layout_id = 86,
361 .codecs[0] = {
362 .name = "onyx",
363 .connections = onyx_connections_nomic,
364 },
365 .codecs[1] = {
366 .name = "topaz",
367 .connections = topaz_input,
368 },
369 },
370 /* PowerBook6,7 */
371 { .layout_id = 92,
372 .codecs[0] = {
373 .name = "tas",
374 .connections = tas_connections_nolineout,
375 },
376 },
377 /* PowerMac10,1 (Mac Mini) */
378 { .layout_id = 58,
379 .codecs[0] = {
380 .name = "toonie",
381 .connections = toonie_connections,
382 },
383 },
384 /* unknown, untested, but this comes from Apple */
385 { .layout_id = 41,
386 .codecs[0] = {
387 .name = "tas",
388 .connections = tas_connections_all,
389 },
390 },
391 { .layout_id = 36,
392 .codecs[0] = {
393 .name = "tas",
394 .connections = tas_connections_nomic,
395 },
396 .codecs[1] = {
397 .name = "topaz",
398 .connections = topaz_inout,
399 },
400 },
401 { .layout_id = 47,
402 .codecs[0] = {
403 .name = "onyx",
404 .connections = onyx_connections_noheadphones,
405 },
406 },
407 { .layout_id = 48,
408 .codecs[0] = {
409 .name = "topaz",
410 .connections = topaz_input,
411 },
412 },
413 { .layout_id = 49,
414 .codecs[0] = {
415 .name = "onyx",
416 .connections = onyx_connections_nomic,
417 },
418 },
419 { .layout_id = 50,
420 .codecs[0] = {
421 .name = "topaz",
422 .connections = topaz_input,
423 },
424 },
425 { .layout_id = 56,
426 .codecs[0] = {
427 .name = "onyx",
428 .connections = onyx_connections_noheadphones,
429 },
430 },
431 { .layout_id = 57,
432 .codecs[0] = {
433 .name = "topaz",
434 .connections = topaz_input,
435 },
436 },
437 { .layout_id = 62,
438 .codecs[0] = {
439 .name = "onyx",
440 .connections = onyx_connections_noheadphones,
441 },
442 .codecs[1] = {
443 .name = "topaz",
444 .connections = topaz_output,
445 },
446 },
447 { .layout_id = 66,
448 .codecs[0] = {
449 .name = "onyx",
450 .connections = onyx_connections_noheadphones,
451 },
452 },
453 { .layout_id = 67,
454 .codecs[0] = {
455 .name = "topaz",
456 .connections = topaz_input,
457 },
458 },
459 { .layout_id = 76,
460 .codecs[0] = {
461 .name = "tas",
462 .connections = tas_connections_nomic,
463 },
464 .codecs[1] = {
465 .name = "topaz",
466 .connections = topaz_inout,
467 },
468 },
469 { .layout_id = 90,
470 .codecs[0] = {
471 .name = "tas",
472 .connections = tas_connections_noline,
473 },
474 },
475 { .layout_id = 94,
476 .codecs[0] = {
477 .name = "onyx",
478 /* but it has an external mic?? how to select? */
479 .connections = onyx_connections_noheadphones,
480 },
481 },
482 { .layout_id = 96,
483 .codecs[0] = {
484 .name = "onyx",
485 .connections = onyx_connections_noheadphones,
486 },
487 },
488 { .layout_id = 98,
489 .codecs[0] = {
490 .name = "toonie",
491 .connections = toonie_connections,
492 },
493 },
494 { .layout_id = 100,
495 .codecs[0] = {
496 .name = "topaz",
497 .connections = topaz_input,
498 },
499 .codecs[1] = {
500 .name = "onyx",
501 .connections = onyx_connections_noheadphones,
502 },
503 },
504 {}
505};
506
507static struct layout *find_layout_by_id(unsigned int id)
508{
509 struct layout *l;
510
511 l = layouts;
512 while (l->layout_id) {
513 if (l->layout_id == id)
514 return l;
515 l++;
516 }
517 return NULL;
518}
519
520static void use_layout(struct layout *l)
521{
522 int i;
523
524 for (i=0; i<MAX_CODECS_PER_BUS; i++) {
525 if (l->codecs[i].name) {
526 request_module("snd-aoa-codec-%s", l->codecs[i].name);
527 }
528 }
529 /* now we wait for the codecs to call us back */
530}
531
532struct layout_dev;
533
534struct layout_dev_ptr {
535 struct layout_dev *ptr;
536};
537
538struct layout_dev {
539 struct list_head list;
540 struct soundbus_dev *sdev;
541 struct device_node *sound;
542 struct aoa_codec *codecs[MAX_CODECS_PER_BUS];
543 struct layout *layout;
544 struct gpio_runtime gpio;
545
546 /* we need these for headphone/lineout detection */
547 struct snd_kcontrol *headphone_ctrl;
548 struct snd_kcontrol *lineout_ctrl;
549 struct snd_kcontrol *speaker_ctrl;
550 struct snd_kcontrol *headphone_detected_ctrl;
551 struct snd_kcontrol *lineout_detected_ctrl;
552
553 struct layout_dev_ptr selfptr_headphone;
554 struct layout_dev_ptr selfptr_lineout;
555
556 u32 have_lineout_detect:1,
557 have_headphone_detect:1,
558 switch_on_headphone:1,
559 switch_on_lineout:1;
560};
561
562static LIST_HEAD(layouts_list);
563static int layouts_list_items;
564/* this can go away but only if we allow multiple cards,
565 * make the fabric handle all the card stuff, etc... */
566static struct layout_dev *layout_device;
567
568static int control_info(struct snd_kcontrol *kcontrol,
569 struct snd_ctl_elem_info *uinfo)
570{
571 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
572 uinfo->count = 1;
573 uinfo->value.integer.min = 0;
574 uinfo->value.integer.max = 1;
575 return 0;
576}
577
578#define AMP_CONTROL(n, description) \
579static int n##_control_get(struct snd_kcontrol *kcontrol, \
580 struct snd_ctl_elem_value *ucontrol) \
581{ \
582 struct gpio_runtime *gpio = snd_kcontrol_chip(kcontrol); \
583 if (gpio->methods && gpio->methods->get_##n) \
584 ucontrol->value.integer.value[0] = \
585 gpio->methods->get_##n(gpio); \
586 return 0; \
587} \
588static int n##_control_put(struct snd_kcontrol *kcontrol, \
589 struct snd_ctl_elem_value *ucontrol) \
590{ \
591 struct gpio_runtime *gpio = snd_kcontrol_chip(kcontrol); \
592 if (gpio->methods && gpio->methods->get_##n) \
593 gpio->methods->set_##n(gpio, \
594 ucontrol->value.integer.value[0]); \
595 return 1; \
596} \
597static struct snd_kcontrol_new n##_ctl = { \
598 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
599 .name = description, \
600 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
601 .info = control_info, \
602 .get = n##_control_get, \
603 .put = n##_control_put, \
604}
605
606AMP_CONTROL(headphone, "Headphone Switch");
607AMP_CONTROL(speakers, "Speakers Switch");
608AMP_CONTROL(lineout, "Line-Out Switch");
609
610static int detect_choice_get(struct snd_kcontrol *kcontrol,
611 struct snd_ctl_elem_value *ucontrol)
612{
613 struct layout_dev *ldev = snd_kcontrol_chip(kcontrol);
614
615 switch (kcontrol->private_value) {
616 case 0:
617 ucontrol->value.integer.value[0] = ldev->switch_on_headphone;
618 break;
619 case 1:
620 ucontrol->value.integer.value[0] = ldev->switch_on_lineout;
621 break;
622 default:
623 return -ENODEV;
624 }
625 return 0;
626}
627
628static int detect_choice_put(struct snd_kcontrol *kcontrol,
629 struct snd_ctl_elem_value *ucontrol)
630{
631 struct layout_dev *ldev = snd_kcontrol_chip(kcontrol);
632
633 switch (kcontrol->private_value) {
634 case 0:
635 ldev->switch_on_headphone = !!ucontrol->value.integer.value[0];
636 break;
637 case 1:
638 ldev->switch_on_lineout = !!ucontrol->value.integer.value[0];
639 break;
640 default:
641 return -ENODEV;
642 }
643 return 1;
644}
645
646static struct snd_kcontrol_new headphone_detect_choice = {
647 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
648 .name = "Headphone Detect Autoswitch",
649 .info = control_info,
650 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
651 .get = detect_choice_get,
652 .put = detect_choice_put,
653 .private_value = 0,
654};
655
656static struct snd_kcontrol_new lineout_detect_choice = {
657 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
658 .name = "Line-Out Detect Autoswitch",
659 .info = control_info,
660 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
661 .get = detect_choice_get,
662 .put = detect_choice_put,
663 .private_value = 1,
664};
665
666static int detected_get(struct snd_kcontrol *kcontrol,
667 struct snd_ctl_elem_value *ucontrol)
668{
669 struct layout_dev *ldev = snd_kcontrol_chip(kcontrol);
670 int v;
671
672 switch (kcontrol->private_value) {
673 case 0:
674 v = ldev->gpio.methods->get_detect(&ldev->gpio,
675 AOA_NOTIFY_HEADPHONE);
676 break;
677 case 1:
678 v = ldev->gpio.methods->get_detect(&ldev->gpio,
679 AOA_NOTIFY_LINE_OUT);
680 break;
681 default:
682 return -ENODEV;
683 }
684 ucontrol->value.integer.value[0] = v;
685 return 0;
686}
687
688static struct snd_kcontrol_new headphone_detected = {
689 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
690 .name = "Headphone Detected",
691 .info = control_info,
692 .access = SNDRV_CTL_ELEM_ACCESS_READ,
693 .get = detected_get,
694 .private_value = 0,
695};
696
697static struct snd_kcontrol_new lineout_detected = {
698 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
699 .name = "Line-Out Detected",
700 .info = control_info,
701 .access = SNDRV_CTL_ELEM_ACCESS_READ,
702 .get = detected_get,
703 .private_value = 1,
704};
705
706static int check_codec(struct aoa_codec *codec,
707 struct layout_dev *ldev,
708 struct codec_connect_info *cci)
709{
710 u32 *ref;
711 char propname[32];
712 struct codec_connection *cc;
713
714 /* if the codec has a 'codec' node, we require a reference */
715 if (codec->node && (strcmp(codec->node->name, "codec") == 0)) {
716 snprintf(propname, sizeof(propname),
717 "platform-%s-codec-ref", codec->name);
718 ref = (u32*)get_property(ldev->sound, propname, NULL);
719 if (!ref) {
720 printk(KERN_INFO "snd-aoa-fabric-layout: "
721 "required property %s not present\n", propname);
722 return -ENODEV;
723 }
724 if (*ref != codec->node->linux_phandle) {
725 printk(KERN_INFO "snd-aoa-fabric-layout: "
726 "%s doesn't match!\n", propname);
727 return -ENODEV;
728 }
729 } else {
730 if (layouts_list_items != 1) {
731 printk(KERN_INFO "snd-aoa-fabric-layout: "
732 "more than one soundbus, but no references.\n");
733 return -ENODEV;
734 }
735 }
736 codec->soundbus_dev = ldev->sdev;
737 codec->gpio = &ldev->gpio;
738
739 cc = cci->connections;
740 if (!cc)
741 return -EINVAL;
742
743 printk(KERN_INFO "snd-aoa-fabric-layout: can use this codec\n");
744
745 codec->connected = 0;
746 codec->fabric_data = cc;
747
748 while (cc->connected) {
749 codec->connected |= 1<<cc->codec_bit;
750 cc++;
751 }
752
753 return 0;
754}
755
756static int layout_found_codec(struct aoa_codec *codec)
757{
758 struct layout_dev *ldev;
759 int i;
760
761 list_for_each_entry(ldev, &layouts_list, list) {
762 for (i=0; i<MAX_CODECS_PER_BUS; i++) {
763 if (!ldev->layout->codecs[i].name)
764 continue;
765 if (strcmp(ldev->layout->codecs[i].name, codec->name) == 0) {
766 if (check_codec(codec,
767 ldev,
768 &ldev->layout->codecs[i]) == 0)
769 return 0;
770 }
771 }
772 }
773 return -ENODEV;
774}
775
776static void layout_remove_codec(struct aoa_codec *codec)
777{
778 int i;
779 /* here remove the codec from the layout dev's
780 * codec reference */
781
782 codec->soundbus_dev = NULL;
783 codec->gpio = NULL;
784 for (i=0; i<MAX_CODECS_PER_BUS; i++) {
785 }
786}
787
788static void layout_notify(void *data)
789{
790 struct layout_dev_ptr *dptr = data;
791 struct layout_dev *ldev;
792 int v, update;
793 struct snd_kcontrol *detected, *c;
794 struct snd_card *card = aoa_get_card();
795
796 ldev = dptr->ptr;
797 if (data == &ldev->selfptr_headphone) {
798 v = ldev->gpio.methods->get_detect(&ldev->gpio, AOA_NOTIFY_HEADPHONE);
799 detected = ldev->headphone_detected_ctrl;
800 update = ldev->switch_on_headphone;
801 if (update) {
802 ldev->gpio.methods->set_speakers(&ldev->gpio, !v);
803 ldev->gpio.methods->set_headphone(&ldev->gpio, v);
804 ldev->gpio.methods->set_lineout(&ldev->gpio, 0);
805 }
806 } else if (data == &ldev->selfptr_lineout) {
807 v = ldev->gpio.methods->get_detect(&ldev->gpio, AOA_NOTIFY_LINE_OUT);
808 detected = ldev->lineout_detected_ctrl;
809 update = ldev->switch_on_lineout;
810 if (update) {
811 ldev->gpio.methods->set_speakers(&ldev->gpio, !v);
812 ldev->gpio.methods->set_headphone(&ldev->gpio, 0);
813 ldev->gpio.methods->set_lineout(&ldev->gpio, v);
814 }
815 } else
816 return;
817
818 if (detected)
819 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &detected->id);
820 if (update) {
821 c = ldev->headphone_ctrl;
822 if (c)
823 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &c->id);
824 c = ldev->speaker_ctrl;
825 if (c)
826 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &c->id);
827 c = ldev->lineout_ctrl;
828 if (c)
829 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &c->id);
830 }
831}
832
833static void layout_attached_codec(struct aoa_codec *codec)
834{
835 struct codec_connection *cc;
836 struct snd_kcontrol *ctl;
837 int headphones, lineout;
838 struct layout_dev *ldev = layout_device;
839
840 /* need to add this codec to our codec array! */
841
842 cc = codec->fabric_data;
843
844 headphones = codec->gpio->methods->get_detect(codec->gpio,
845 AOA_NOTIFY_HEADPHONE);
846 lineout = codec->gpio->methods->get_detect(codec->gpio,
847 AOA_NOTIFY_LINE_OUT);
848
849 while (cc->connected) {
850 if (cc->connected & CC_SPEAKERS) {
851 if (headphones <= 0 && lineout <= 0)
852 ldev->gpio.methods->set_speakers(codec->gpio, 1);
853 ctl = snd_ctl_new1(&speakers_ctl, codec->gpio);
854 ldev->speaker_ctrl = ctl;
855 aoa_snd_ctl_add(ctl);
856 }
857 if (cc->connected & CC_HEADPHONE) {
858 if (headphones == 1)
859 ldev->gpio.methods->set_headphone(codec->gpio, 1);
860 ctl = snd_ctl_new1(&headphone_ctl, codec->gpio);
861 ldev->headphone_ctrl = ctl;
862 aoa_snd_ctl_add(ctl);
863 ldev->have_headphone_detect =
864 !ldev->gpio.methods
865 ->set_notify(&ldev->gpio,
866 AOA_NOTIFY_HEADPHONE,
867 layout_notify,
868 &ldev->selfptr_headphone);
869 if (ldev->have_headphone_detect) {
870 ctl = snd_ctl_new1(&headphone_detect_choice,
871 ldev);
872 aoa_snd_ctl_add(ctl);
873 ctl = snd_ctl_new1(&headphone_detected,
874 ldev);
875 ldev->headphone_detected_ctrl = ctl;
876 aoa_snd_ctl_add(ctl);
877 }
878 }
879 if (cc->connected & CC_LINEOUT) {
880 if (lineout == 1)
881 ldev->gpio.methods->set_lineout(codec->gpio, 1);
882 ctl = snd_ctl_new1(&lineout_ctl, codec->gpio);
883 if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
884 strlcpy(ctl->id.name,
885 "Headphone Switch", sizeof(ctl->id.name));
886 ldev->lineout_ctrl = ctl;
887 aoa_snd_ctl_add(ctl);
888 ldev->have_lineout_detect =
889 !ldev->gpio.methods
890 ->set_notify(&ldev->gpio,
891 AOA_NOTIFY_LINE_OUT,
892 layout_notify,
893 &ldev->selfptr_lineout);
894 if (ldev->have_lineout_detect) {
895 ctl = snd_ctl_new1(&lineout_detect_choice,
896 ldev);
897 if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
898 strlcpy(ctl->id.name,
899 "Headphone Detect Autoswitch",
900 sizeof(ctl->id.name));
901 aoa_snd_ctl_add(ctl);
902 ctl = snd_ctl_new1(&lineout_detected,
903 ldev);
904 if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
905 strlcpy(ctl->id.name,
906 "Headphone Detected",
907 sizeof(ctl->id.name));
908 ldev->lineout_detected_ctrl = ctl;
909 aoa_snd_ctl_add(ctl);
910 }
911 }
912 cc++;
913 }
914 /* now update initial state */
915 if (ldev->have_headphone_detect)
916 layout_notify(&ldev->selfptr_headphone);
917 if (ldev->have_lineout_detect)
918 layout_notify(&ldev->selfptr_lineout);
919}
920
921static struct aoa_fabric layout_fabric = {
922 .name = "SoundByLayout",
923 .owner = THIS_MODULE,
924 .found_codec = layout_found_codec,
925 .remove_codec = layout_remove_codec,
926 .attached_codec = layout_attached_codec,
927};
928
929static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
930{
931 struct device_node *sound = NULL;
932 unsigned int *layout_id;
933 struct layout *layout;
934 struct layout_dev *ldev = NULL;
935 int err;
936
937 /* hm, currently we can only have one ... */
938 if (layout_device)
939 return -ENODEV;
940
941 /* by breaking out we keep a reference */
942 while ((sound = of_get_next_child(sdev->ofdev.node, sound))) {
943 if (sound->type && strcasecmp(sound->type, "soundchip") == 0)
944 break;
945 }
946 if (!sound) return -ENODEV;
947
948 layout_id = (unsigned int *) get_property(sound, "layout-id", NULL);
949 if (!layout_id)
950 goto outnodev;
951 printk(KERN_INFO "snd-aoa-fabric-layout: found bus with layout %d ", *layout_id);
952
953 layout = find_layout_by_id(*layout_id);
954 if (!layout) {
955 printk("(no idea how to handle)\n");
956 goto outnodev;
957 }
958
959 ldev = kzalloc(sizeof(struct layout_dev), GFP_KERNEL);
960 if (!ldev)
961 goto outnodev;
962
963 layout_device = ldev;
964 ldev->sdev = sdev;
965 ldev->sound = sound;
966 ldev->layout = layout;
967 ldev->gpio.node = sound->parent;
968 switch (layout->layout_id) {
969 case 41: /* that unknown machine no one seems to have */
970 case 51: /* PowerBook5,4 */
971 case 58: /* Mac Mini */
972 ldev->gpio.methods = ftr_gpio_methods;
973 break;
974 default:
975 ldev->gpio.methods = pmf_gpio_methods;
976 }
977 ldev->selfptr_headphone.ptr = ldev;
978 ldev->selfptr_lineout.ptr = ldev;
979 sdev->ofdev.dev.driver_data = ldev;
980
981 printk("(using)\n");
982 list_add(&ldev->list, &layouts_list);
983 layouts_list_items++;
984
985 /* assign these before registering ourselves, so
986 * callbacks that are done during registration
987 * already have the values */
988 sdev->pcmid = ldev->layout->pcmid;
989 if (ldev->layout->busname) {
990 sdev->pcmname = ldev->layout->busname;
991 } else {
992 sdev->pcmname = "Master";
993 }
994
995 ldev->gpio.methods->init(&ldev->gpio);
996
997 err = aoa_fabric_register(&layout_fabric);
998 if (err && err != -EALREADY) {
999 printk(KERN_INFO "snd-aoa-fabric-layout: can't use,"
1000 " another fabric is active!\n");
1001 goto outlistdel;
1002 }
1003
1004 use_layout(layout);
1005 ldev->switch_on_headphone = 1;
1006 ldev->switch_on_lineout = 1;
1007 return 0;
1008 outlistdel:
1009 /* we won't be using these then... */
1010 ldev->gpio.methods->exit(&ldev->gpio);
1011 /* reset if we didn't use it */
1012 sdev->pcmname = NULL;
1013 sdev->pcmid = -1;
1014 list_del(&ldev->list);
1015 layouts_list_items--;
1016 outnodev:
1017 if (sound) of_node_put(sound);
1018 layout_device = NULL;
1019 if (ldev) kfree(ldev);
1020 return -ENODEV;
1021}
1022
1023static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
1024{
1025 struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
1026 int i;
1027
1028 for (i=0; i<MAX_CODECS_PER_BUS; i++) {
1029 if (ldev->codecs[i]) {
1030 aoa_fabric_unlink_codec(ldev->codecs[i]);
1031 }
1032 ldev->codecs[i] = NULL;
1033 }
1034 list_del(&ldev->list);
1035 layouts_list_items--;
1036 of_node_put(ldev->sound);
1037
1038 ldev->gpio.methods->set_notify(&ldev->gpio,
1039 AOA_NOTIFY_HEADPHONE,
1040 NULL,
1041 NULL);
1042 ldev->gpio.methods->set_notify(&ldev->gpio,
1043 AOA_NOTIFY_LINE_OUT,
1044 NULL,
1045 NULL);
1046
1047 ldev->gpio.methods->exit(&ldev->gpio);
1048 layout_device = NULL;
1049 kfree(ldev);
1050 sdev->pcmid = -1;
1051 sdev->pcmname = NULL;
1052 return 0;
1053}
1054
1055#ifdef CONFIG_PM
1056static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t state)
1057{
1058 struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
1059
1060 printk("aoa_fabric_layout_suspend()\n");
1061
1062 if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
1063 ldev->gpio.methods->all_amps_off(&ldev->gpio);
1064
1065 return 0;
1066}
1067
1068static int aoa_fabric_layout_resume(struct soundbus_dev *sdev)
1069{
1070 struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
1071
1072 printk("aoa_fabric_layout_resume()\n");
1073
1074 if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
1075 ldev->gpio.methods->all_amps_restore(&ldev->gpio);
1076
1077 return 0;
1078}
1079#endif
1080
1081static struct soundbus_driver aoa_soundbus_driver = {
1082 .name = "snd_aoa_soundbus_drv",
1083 .owner = THIS_MODULE,
1084 .probe = aoa_fabric_layout_probe,
1085 .remove = aoa_fabric_layout_remove,
1086#ifdef CONFIG_PM
1087 .suspend = aoa_fabric_layout_suspend,
1088 .resume = aoa_fabric_layout_resume,
1089#endif
1090};
1091
1092static int __init aoa_fabric_layout_init(void)
1093{
1094 int err;
1095
1096 err = soundbus_register_driver(&aoa_soundbus_driver);
1097 if (err)
1098 return err;
1099 return 0;
1100}
1101
1102static void __exit aoa_fabric_layout_exit(void)
1103{
1104 soundbus_unregister_driver(&aoa_soundbus_driver);
1105 aoa_fabric_unregister(&layout_fabric);
1106}
1107
1108module_init(aoa_fabric_layout_init);
1109module_exit(aoa_fabric_layout_exit);
diff --git a/sound/aoa/soundbus/Kconfig b/sound/aoa/soundbus/Kconfig
new file mode 100644
index 000000000000..d532d27a9f54
--- /dev/null
+++ b/sound/aoa/soundbus/Kconfig
@@ -0,0 +1,14 @@
1config SND_AOA_SOUNDBUS
2 tristate "Apple Soundbus support"
3 depends on SOUND && SND_PCM && EXPERIMENTAL
4 ---help---
5 This option enables the generic driver for the soundbus
6 support on Apple machines.
7
8 It is required for the sound bus implementations.
9
10config SND_AOA_SOUNDBUS_I2S
11 tristate "I2S bus support"
12 depends on SND_AOA_SOUNDBUS && PCI
13 ---help---
14 This option enables support for Apple I2S busses.
diff --git a/sound/aoa/soundbus/Makefile b/sound/aoa/soundbus/Makefile
new file mode 100644
index 000000000000..0e61f5aa06b5
--- /dev/null
+++ b/sound/aoa/soundbus/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_SND_AOA_SOUNDBUS) += snd-aoa-soundbus.o
2snd-aoa-soundbus-objs := core.o sysfs.o
3obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += i2sbus/
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c
new file mode 100644
index 000000000000..abe84a76c835
--- /dev/null
+++ b/sound/aoa/soundbus/core.c
@@ -0,0 +1,250 @@
1/*
2 * soundbus
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#include <linux/module.h>
10#include "soundbus.h"
11
12MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
13MODULE_LICENSE("GPL");
14MODULE_DESCRIPTION("Apple Soundbus");
15
16struct soundbus_dev *soundbus_dev_get(struct soundbus_dev *dev)
17{
18 struct device *tmp;
19
20 if (!dev)
21 return NULL;
22 tmp = get_device(&dev->ofdev.dev);
23 if (tmp)
24 return to_soundbus_device(tmp);
25 else
26 return NULL;
27}
28EXPORT_SYMBOL_GPL(soundbus_dev_get);
29
30void soundbus_dev_put(struct soundbus_dev *dev)
31{
32 if (dev)
33 put_device(&dev->ofdev.dev);
34}
35EXPORT_SYMBOL_GPL(soundbus_dev_put);
36
37static int soundbus_probe(struct device *dev)
38{
39 int error = -ENODEV;
40 struct soundbus_driver *drv;
41 struct soundbus_dev *soundbus_dev;
42
43 drv = to_soundbus_driver(dev->driver);
44 soundbus_dev = to_soundbus_device(dev);
45
46 if (!drv->probe)
47 return error;
48
49 soundbus_dev_get(soundbus_dev);
50
51 error = drv->probe(soundbus_dev);
52 if (error)
53 soundbus_dev_put(soundbus_dev);
54
55 return error;
56}
57
58
59static int soundbus_uevent(struct device *dev, char **envp, int num_envp,
60 char *buffer, int buffer_size)
61{
62 struct soundbus_dev * soundbus_dev;
63 struct of_device * of;
64 char *scratch, *compat, *compat2;
65 int i = 0;
66 int length, cplen, cplen2, seen = 0;
67
68 if (!dev)
69 return -ENODEV;
70
71 soundbus_dev = to_soundbus_device(dev);
72 if (!soundbus_dev)
73 return -ENODEV;
74
75 of = &soundbus_dev->ofdev;
76
77 /* stuff we want to pass to /sbin/hotplug */
78 envp[i++] = scratch = buffer;
79 length = scnprintf (scratch, buffer_size, "OF_NAME=%s", of->node->name);
80 ++length;
81 buffer_size -= length;
82 if ((buffer_size <= 0) || (i >= num_envp))
83 return -ENOMEM;
84 scratch += length;
85
86 envp[i++] = scratch;
87 length = scnprintf (scratch, buffer_size, "OF_TYPE=%s", of->node->type);
88 ++length;
89 buffer_size -= length;
90 if ((buffer_size <= 0) || (i >= num_envp))
91 return -ENOMEM;
92 scratch += length;
93
94 /* Since the compatible field can contain pretty much anything
95 * it's not really legal to split it out with commas. We split it
96 * up using a number of environment variables instead. */
97
98 compat = (char *) get_property(of->node, "compatible", &cplen);
99 compat2 = compat;
100 cplen2= cplen;
101 while (compat && cplen > 0) {
102 envp[i++] = scratch;
103 length = scnprintf (scratch, buffer_size,
104 "OF_COMPATIBLE_%d=%s", seen, compat);
105 ++length;
106 buffer_size -= length;
107 if ((buffer_size <= 0) || (i >= num_envp))
108 return -ENOMEM;
109 scratch += length;
110 length = strlen (compat) + 1;
111 compat += length;
112 cplen -= length;
113 seen++;
114 }
115
116 envp[i++] = scratch;
117 length = scnprintf (scratch, buffer_size, "OF_COMPATIBLE_N=%d", seen);
118 ++length;
119 buffer_size -= length;
120 if ((buffer_size <= 0) || (i >= num_envp))
121 return -ENOMEM;
122 scratch += length;
123
124 envp[i++] = scratch;
125 length = scnprintf (scratch, buffer_size, "MODALIAS=%s",
126 soundbus_dev->modalias);
127
128 buffer_size -= length;
129 if ((buffer_size <= 0) || (i >= num_envp))
130 return -ENOMEM;
131
132 envp[i] = NULL;
133
134 return 0;
135}
136
137static int soundbus_device_remove(struct device *dev)
138{
139 struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
140 struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
141
142 if (dev->driver && drv->remove)
143 drv->remove(soundbus_dev);
144 soundbus_dev_put(soundbus_dev);
145
146 return 0;
147}
148
149static void soundbus_device_shutdown(struct device *dev)
150{
151 struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
152 struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
153
154 if (dev->driver && drv->shutdown)
155 drv->shutdown(soundbus_dev);
156}
157
158#ifdef CONFIG_PM
159
160static int soundbus_device_suspend(struct device *dev, pm_message_t state)
161{
162 struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
163 struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
164
165 if (dev->driver && drv->suspend)
166 return drv->suspend(soundbus_dev, state);
167 return 0;
168}
169
170static int soundbus_device_resume(struct device * dev)
171{
172 struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
173 struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
174
175 if (dev->driver && drv->resume)
176 return drv->resume(soundbus_dev);
177 return 0;
178}
179
180#endif /* CONFIG_PM */
181
182extern struct device_attribute soundbus_dev_attrs[];
183
184static struct bus_type soundbus_bus_type = {
185 .name = "aoa-soundbus",
186 .probe = soundbus_probe,
187 .uevent = soundbus_uevent,
188 .remove = soundbus_device_remove,
189 .shutdown = soundbus_device_shutdown,
190#ifdef CONFIG_PM
191 .suspend = soundbus_device_suspend,
192 .resume = soundbus_device_resume,
193#endif
194 .dev_attrs = soundbus_dev_attrs,
195};
196
197static int __init soundbus_init(void)
198{
199 return bus_register(&soundbus_bus_type);
200}
201
202static void __exit soundbus_exit(void)
203{
204 bus_unregister(&soundbus_bus_type);
205}
206
207int soundbus_add_one(struct soundbus_dev *dev)
208{
209 static int devcount;
210
211 /* sanity checks */
212 if (!dev->attach_codec ||
213 !dev->ofdev.node ||
214 dev->pcmname ||
215 dev->pcmid != -1) {
216 printk(KERN_ERR "soundbus: adding device failed sanity check!\n");
217 return -EINVAL;
218 }
219
220 snprintf(dev->ofdev.dev.bus_id, BUS_ID_SIZE, "soundbus:%x", ++devcount);
221 dev->ofdev.dev.bus = &soundbus_bus_type;
222 return of_device_register(&dev->ofdev);
223}
224EXPORT_SYMBOL_GPL(soundbus_add_one);
225
226void soundbus_remove_one(struct soundbus_dev *dev)
227{
228 of_device_unregister(&dev->ofdev);
229}
230EXPORT_SYMBOL_GPL(soundbus_remove_one);
231
232int soundbus_register_driver(struct soundbus_driver *drv)
233{
234 /* initialize common driver fields */
235 drv->driver.name = drv->name;
236 drv->driver.bus = &soundbus_bus_type;
237
238 /* register with core */
239 return driver_register(&drv->driver);
240}
241EXPORT_SYMBOL_GPL(soundbus_register_driver);
242
243void soundbus_unregister_driver(struct soundbus_driver *drv)
244{
245 driver_unregister(&drv->driver);
246}
247EXPORT_SYMBOL_GPL(soundbus_unregister_driver);
248
249module_init(soundbus_init);
250module_exit(soundbus_exit);
diff --git a/sound/aoa/soundbus/i2sbus/Makefile b/sound/aoa/soundbus/i2sbus/Makefile
new file mode 100644
index 000000000000..e57a5cf65655
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/Makefile
@@ -0,0 +1,2 @@
1obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += snd-aoa-i2sbus.o
2snd-aoa-i2sbus-objs := i2sbus-core.o i2sbus-pcm.o i2sbus-control.o
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-control.c b/sound/aoa/soundbus/i2sbus/i2sbus-control.c
new file mode 100644
index 000000000000..f50407952d3c
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-control.c
@@ -0,0 +1,192 @@
1/*
2 * i2sbus driver -- bus control routines
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#include <asm/io.h>
10#include <linux/delay.h>
11#include <asm/prom.h>
12#include <asm/macio.h>
13#include <asm/pmac_feature.h>
14#include <asm/pmac_pfunc.h>
15#include "i2sbus.h"
16
17int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c)
18{
19 *c = kzalloc(sizeof(struct i2sbus_control), GFP_KERNEL);
20 if (!*c)
21 return -ENOMEM;
22
23 INIT_LIST_HEAD(&(*c)->list);
24
25 if (of_address_to_resource(dev->ofdev.node, 0, &(*c)->rsrc))
26 goto err;
27 /* we really should be using feature calls instead of mapping
28 * these registers. It's safe for now since no one else is
29 * touching them... */
30 (*c)->controlregs = ioremap((*c)->rsrc.start,
31 sizeof(struct i2s_control_regs));
32 if (!(*c)->controlregs)
33 goto err;
34
35 return 0;
36 err:
37 kfree(*c);
38 *c = NULL;
39 return -ENODEV;
40}
41
42void i2sbus_control_destroy(struct i2sbus_control *c)
43{
44 iounmap(c->controlregs);
45 kfree(c);
46}
47
48/* this is serialised externally */
49int i2sbus_control_add_dev(struct i2sbus_control *c,
50 struct i2sbus_dev *i2sdev)
51{
52 struct device_node *np;
53
54 np = i2sdev->sound.ofdev.node;
55 i2sdev->enable = pmf_find_function(np, "enable");
56 i2sdev->cell_enable = pmf_find_function(np, "cell-enable");
57 i2sdev->clock_enable = pmf_find_function(np, "clock-enable");
58 i2sdev->cell_disable = pmf_find_function(np, "cell-disable");
59 i2sdev->clock_disable = pmf_find_function(np, "clock-disable");
60
61 /* if the bus number is not 0 or 1 we absolutely need to use
62 * the platform functions -- there's nothing in Darwin that
63 * would allow seeing a system behind what the FCRs are then,
64 * and I don't want to go parsing a bunch of platform functions
65 * by hand to try finding a system... */
66 if (i2sdev->bus_number != 0 && i2sdev->bus_number != 1 &&
67 (!i2sdev->enable ||
68 !i2sdev->cell_enable || !i2sdev->clock_enable ||
69 !i2sdev->cell_disable || !i2sdev->clock_disable)) {
70 pmf_put_function(i2sdev->enable);
71 pmf_put_function(i2sdev->cell_enable);
72 pmf_put_function(i2sdev->clock_enable);
73 pmf_put_function(i2sdev->cell_disable);
74 pmf_put_function(i2sdev->clock_disable);
75 return -ENODEV;
76 }
77
78 list_add(&i2sdev->item, &c->list);
79
80 return 0;
81}
82
83void i2sbus_control_remove_dev(struct i2sbus_control *c,
84 struct i2sbus_dev *i2sdev)
85{
86 /* this is serialised externally */
87 list_del(&i2sdev->item);
88 if (list_empty(&c->list))
89 i2sbus_control_destroy(c);
90}
91
92int i2sbus_control_enable(struct i2sbus_control *c,
93 struct i2sbus_dev *i2sdev)
94{
95 struct pmf_args args = { .count = 0 };
96 int cc;
97
98 if (i2sdev->enable)
99 return pmf_call_one(i2sdev->enable, &args);
100
101 switch (i2sdev->bus_number) {
102 case 0:
103 cc = in_le32(&c->controlregs->cell_control);
104 out_le32(&c->controlregs->cell_control, cc | CTRL_CLOCK_INTF_0_ENABLE);
105 break;
106 case 1:
107 cc = in_le32(&c->controlregs->cell_control);
108 out_le32(&c->controlregs->cell_control, cc | CTRL_CLOCK_INTF_1_ENABLE);
109 break;
110 default:
111 return -ENODEV;
112 }
113 return 0;
114}
115
116int i2sbus_control_cell(struct i2sbus_control *c,
117 struct i2sbus_dev *i2sdev,
118 int enable)
119{
120 struct pmf_args args = { .count = 0 };
121 int cc;
122
123 switch (enable) {
124 case 0:
125 if (i2sdev->cell_disable)
126 return pmf_call_one(i2sdev->cell_disable, &args);
127 break;
128 case 1:
129 if (i2sdev->cell_enable)
130 return pmf_call_one(i2sdev->cell_enable, &args);
131 break;
132 default:
133 printk(KERN_ERR "i2sbus: INVALID CELL ENABLE VALUE\n");
134 return -ENODEV;
135 }
136 switch (i2sdev->bus_number) {
137 case 0:
138 cc = in_le32(&c->controlregs->cell_control);
139 cc &= ~CTRL_CLOCK_CELL_0_ENABLE;
140 cc |= enable * CTRL_CLOCK_CELL_0_ENABLE;
141 out_le32(&c->controlregs->cell_control, cc);
142 break;
143 case 1:
144 cc = in_le32(&c->controlregs->cell_control);
145 cc &= ~CTRL_CLOCK_CELL_1_ENABLE;
146 cc |= enable * CTRL_CLOCK_CELL_1_ENABLE;
147 out_le32(&c->controlregs->cell_control, cc);
148 break;
149 default:
150 return -ENODEV;
151 }
152 return 0;
153}
154
155int i2sbus_control_clock(struct i2sbus_control *c,
156 struct i2sbus_dev *i2sdev,
157 int enable)
158{
159 struct pmf_args args = { .count = 0 };
160 int cc;
161
162 switch (enable) {
163 case 0:
164 if (i2sdev->clock_disable)
165 return pmf_call_one(i2sdev->clock_disable, &args);
166 break;
167 case 1:
168 if (i2sdev->clock_enable)
169 return pmf_call_one(i2sdev->clock_enable, &args);
170 break;
171 default:
172 printk(KERN_ERR "i2sbus: INVALID CLOCK ENABLE VALUE\n");
173 return -ENODEV;
174 }
175 switch (i2sdev->bus_number) {
176 case 0:
177 cc = in_le32(&c->controlregs->cell_control);
178 cc &= ~CTRL_CLOCK_CLOCK_0_ENABLE;
179 cc |= enable * CTRL_CLOCK_CLOCK_0_ENABLE;
180 out_le32(&c->controlregs->cell_control, cc);
181 break;
182 case 1:
183 cc = in_le32(&c->controlregs->cell_control);
184 cc &= ~CTRL_CLOCK_CLOCK_1_ENABLE;
185 cc |= enable * CTRL_CLOCK_CLOCK_1_ENABLE;
186 out_le32(&c->controlregs->cell_control, cc);
187 break;
188 default:
189 return -ENODEV;
190 }
191 return 0;
192}
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-control.h b/sound/aoa/soundbus/i2sbus/i2sbus-control.h
new file mode 100644
index 000000000000..bb05550f730b
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-control.h
@@ -0,0 +1,37 @@
1/*
2 * i2sbus driver -- bus register definitions
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#ifndef __I2SBUS_CONTROLREGS_H
9#define __I2SBUS_CONTROLREGS_H
10
11/* i2s control registers, at least what we know about them */
12
13#define __PAD(m,n) u8 __pad##m[n]
14#define _PAD(line, n) __PAD(line, n)
15#define PAD(n) _PAD(__LINE__, (n))
16struct i2s_control_regs {
17 PAD(0x38);
18 __le32 fcr0; /* 0x38 (unknown) */
19 __le32 cell_control; /* 0x3c (fcr1) */
20 __le32 fcr2; /* 0x40 (unknown) */
21 __le32 fcr3; /* 0x44 (fcr3) */
22 __le32 clock_control; /* 0x48 (unknown) */
23 PAD(4);
24 /* total size: 0x50 bytes */
25} __attribute__((__packed__));
26
27#define CTRL_CLOCK_CELL_0_ENABLE (1<<10)
28#define CTRL_CLOCK_CLOCK_0_ENABLE (1<<12)
29#define CTRL_CLOCK_SWRESET_0 (1<<11)
30#define CTRL_CLOCK_INTF_0_ENABLE (1<<13)
31
32#define CTRL_CLOCK_CELL_1_ENABLE (1<<17)
33#define CTRL_CLOCK_CLOCK_1_ENABLE (1<<18)
34#define CTRL_CLOCK_SWRESET_1 (1<<19)
35#define CTRL_CLOCK_INTF_1_ENABLE (1<<20)
36
37#endif /* __I2SBUS_CONTROLREGS_H */
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
new file mode 100644
index 000000000000..f268dacdaa00
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
@@ -0,0 +1,387 @@
1/*
2 * i2sbus driver
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#include <linux/module.h>
10#include <asm/macio.h>
11#include <asm/dbdma.h>
12#include <linux/pci.h>
13#include <linux/interrupt.h>
14#include <sound/driver.h>
15#include <sound/core.h>
16#include <linux/dma-mapping.h>
17#include "../soundbus.h"
18#include "i2sbus.h"
19
20MODULE_LICENSE("GPL");
21MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
22MODULE_DESCRIPTION("Apple Soundbus: I2S support");
23/* for auto-loading, declare that we handle this weird
24 * string that macio puts into the relevant device */
25MODULE_ALIAS("of:Ni2sTi2sC");
26
27static struct of_device_id i2sbus_match[] = {
28 { .name = "i2s" },
29 { }
30};
31
32static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
33 struct dbdma_command_mem *r,
34 int numcmds)
35{
36 /* one more for rounding */
37 r->size = (numcmds+1) * sizeof(struct dbdma_cmd);
38 /* We use the PCI APIs for now until the generic one gets fixed
39 * enough or until we get some macio-specific versions
40 */
41 r->space = dma_alloc_coherent(
42 &macio_get_pci_dev(i2sdev->macio)->dev,
43 r->size,
44 &r->bus_addr,
45 GFP_KERNEL);
46
47 if (!r->space) return -ENOMEM;
48
49 memset(r->space, 0, r->size);
50 r->cmds = (void*)DBDMA_ALIGN(r->space);
51 r->bus_cmd_start = r->bus_addr +
52 (dma_addr_t)((char*)r->cmds - (char*)r->space);
53
54 return 0;
55}
56
57static void free_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
58 struct dbdma_command_mem *r)
59{
60 if (!r->space) return;
61
62 dma_free_coherent(&macio_get_pci_dev(i2sdev->macio)->dev,
63 r->size, r->space, r->bus_addr);
64}
65
66static void i2sbus_release_dev(struct device *dev)
67{
68 struct i2sbus_dev *i2sdev;
69 int i;
70
71 i2sdev = container_of(dev, struct i2sbus_dev, sound.ofdev.dev);
72
73 if (i2sdev->intfregs) iounmap(i2sdev->intfregs);
74 if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma);
75 if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma);
76 for (i=0;i<3;i++)
77 if (i2sdev->allocated_resource[i])
78 release_and_free_resource(i2sdev->allocated_resource[i]);
79 free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring);
80 free_dbdma_descriptor_ring(i2sdev, &i2sdev->in.dbdma_ring);
81 for (i=0;i<3;i++)
82 free_irq(i2sdev->interrupts[i], i2sdev);
83 i2sbus_control_remove_dev(i2sdev->control, i2sdev);
84 mutex_destroy(&i2sdev->lock);
85 kfree(i2sdev);
86}
87
88static irqreturn_t i2sbus_bus_intr(int irq, void *devid, struct pt_regs *regs)
89{
90 struct i2sbus_dev *dev = devid;
91 u32 intreg;
92
93 spin_lock(&dev->low_lock);
94 intreg = in_le32(&dev->intfregs->intr_ctl);
95
96 /* acknowledge interrupt reasons */
97 out_le32(&dev->intfregs->intr_ctl, intreg);
98
99 spin_unlock(&dev->low_lock);
100
101 return IRQ_HANDLED;
102}
103
104static int force;
105module_param(force, int, 0444);
106MODULE_PARM_DESC(force, "Force loading i2sbus even when"
107 " no layout-id property is present");
108
109/* FIXME: look at device node refcounting */
110static int i2sbus_add_dev(struct macio_dev *macio,
111 struct i2sbus_control *control,
112 struct device_node *np)
113{
114 struct i2sbus_dev *dev;
115 struct device_node *child = NULL, *sound = NULL;
116 int i;
117 static const char *rnames[] = { "i2sbus: %s (control)",
118 "i2sbus: %s (tx)",
119 "i2sbus: %s (rx)" };
120 static irqreturn_t (*ints[])(int irq, void *devid,
121 struct pt_regs *regs) = {
122 i2sbus_bus_intr,
123 i2sbus_tx_intr,
124 i2sbus_rx_intr
125 };
126
127 if (strlen(np->name) != 5)
128 return 0;
129 if (strncmp(np->name, "i2s-", 4))
130 return 0;
131
132 if (np->n_intrs != 3)
133 return 0;
134
135 dev = kzalloc(sizeof(struct i2sbus_dev), GFP_KERNEL);
136 if (!dev)
137 return 0;
138
139 i = 0;
140 while ((child = of_get_next_child(np, child))) {
141 if (strcmp(child->name, "sound") == 0) {
142 i++;
143 sound = child;
144 }
145 }
146 if (i == 1) {
147 u32 *layout_id;
148 layout_id = (u32*) get_property(sound, "layout-id", NULL);
149 if (layout_id) {
150 snprintf(dev->sound.modalias, 32,
151 "sound-layout-%d", *layout_id);
152 force = 1;
153 }
154 }
155 /* for the time being, until we can handle non-layout-id
156 * things in some fabric, refuse to attach if there is no
157 * layout-id property or we haven't been forced to attach.
158 * When there are two i2s busses and only one has a layout-id,
159 * then this depends on the order, but that isn't important
160 * either as the second one in that case is just a modem. */
161 if (!force) {
162 kfree(dev);
163 return -ENODEV;
164 }
165
166 mutex_init(&dev->lock);
167 spin_lock_init(&dev->low_lock);
168 dev->sound.ofdev.node = np;
169 dev->sound.ofdev.dma_mask = macio->ofdev.dma_mask;
170 dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.dma_mask;
171 dev->sound.ofdev.dev.parent = &macio->ofdev.dev;
172 dev->sound.ofdev.dev.release = i2sbus_release_dev;
173 dev->sound.attach_codec = i2sbus_attach_codec;
174 dev->sound.detach_codec = i2sbus_detach_codec;
175 dev->sound.pcmid = -1;
176 dev->macio = macio;
177 dev->control = control;
178 dev->bus_number = np->name[4] - 'a';
179 INIT_LIST_HEAD(&dev->sound.codec_list);
180
181 for (i=0;i<3;i++) {
182 dev->interrupts[i] = -1;
183 snprintf(dev->rnames[i], sizeof(dev->rnames[i]), rnames[i], np->name);
184 }
185 for (i=0;i<3;i++) {
186 if (request_irq(np->intrs[i].line, ints[i], 0, dev->rnames[i], dev))
187 goto err;
188 dev->interrupts[i] = np->intrs[i].line;
189 }
190
191 for (i=0;i<3;i++) {
192 if (of_address_to_resource(np, i, &dev->resources[i]))
193 goto err;
194 /* if only we could use our resource dev->resources[i]...
195 * but request_resource doesn't know about parents and
196 * contained resources... */
197 dev->allocated_resource[i] =
198 request_mem_region(dev->resources[i].start,
199 dev->resources[i].end -
200 dev->resources[i].start + 1,
201 dev->rnames[i]);
202 if (!dev->allocated_resource[i]) {
203 printk(KERN_ERR "i2sbus: failed to claim resource %d!\n", i);
204 goto err;
205 }
206 }
207 /* should do sanity checking here about length of them */
208 dev->intfregs = ioremap(dev->resources[0].start,
209 dev->resources[0].end-dev->resources[0].start+1);
210 dev->out.dbdma = ioremap(dev->resources[1].start,
211 dev->resources[1].end-dev->resources[1].start+1);
212 dev->in.dbdma = ioremap(dev->resources[2].start,
213 dev->resources[2].end-dev->resources[2].start+1);
214 if (!dev->intfregs || !dev->out.dbdma || !dev->in.dbdma)
215 goto err;
216
217 if (alloc_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring,
218 MAX_DBDMA_COMMANDS))
219 goto err;
220 if (alloc_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring,
221 MAX_DBDMA_COMMANDS))
222 goto err;
223
224 if (i2sbus_control_add_dev(dev->control, dev)) {
225 printk(KERN_ERR "i2sbus: control layer didn't like bus\n");
226 goto err;
227 }
228
229 if (soundbus_add_one(&dev->sound)) {
230 printk(KERN_DEBUG "i2sbus: device registration error!\n");
231 goto err;
232 }
233
234 /* enable this cell */
235 i2sbus_control_cell(dev->control, dev, 1);
236 i2sbus_control_enable(dev->control, dev);
237 i2sbus_control_clock(dev->control, dev, 1);
238
239 return 1;
240 err:
241 for (i=0;i<3;i++)
242 if (dev->interrupts[i] != -1)
243 free_irq(dev->interrupts[i], dev);
244 free_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring);
245 free_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring);
246 if (dev->intfregs) iounmap(dev->intfregs);
247 if (dev->out.dbdma) iounmap(dev->out.dbdma);
248 if (dev->in.dbdma) iounmap(dev->in.dbdma);
249 for (i=0;i<3;i++)
250 if (dev->allocated_resource[i])
251 release_and_free_resource(dev->allocated_resource[i]);
252 mutex_destroy(&dev->lock);
253 kfree(dev);
254 return 0;
255}
256
257static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match)
258{
259 struct device_node *np = NULL;
260 int got = 0, err;
261 struct i2sbus_control *control = NULL;
262
263 err = i2sbus_control_init(dev, &control);
264 if (err)
265 return err;
266 if (!control) {
267 printk(KERN_ERR "i2sbus_control_init API breakage\n");
268 return -ENODEV;
269 }
270
271 while ((np = of_get_next_child(dev->ofdev.node, np))) {
272 if (device_is_compatible(np, "i2sbus") ||
273 device_is_compatible(np, "i2s-modem")) {
274 got += i2sbus_add_dev(dev, control, np);
275 }
276 }
277
278 if (!got) {
279 /* found none, clean up */
280 i2sbus_control_destroy(control);
281 return -ENODEV;
282 }
283
284 dev->ofdev.dev.driver_data = control;
285
286 return 0;
287}
288
289static int i2sbus_remove(struct macio_dev* dev)
290{
291 struct i2sbus_control *control = dev->ofdev.dev.driver_data;
292 struct i2sbus_dev *i2sdev, *tmp;
293
294 list_for_each_entry_safe(i2sdev, tmp, &control->list, item)
295 soundbus_remove_one(&i2sdev->sound);
296
297 return 0;
298}
299
300#ifdef CONFIG_PM
301static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
302{
303 struct i2sbus_control *control = dev->ofdev.dev.driver_data;
304 struct codec_info_item *cii;
305 struct i2sbus_dev* i2sdev;
306 int err, ret = 0;
307
308 list_for_each_entry(i2sdev, &control->list, item) {
309 /* Notify Alsa */
310 if (i2sdev->sound.pcm) {
311 /* Suspend PCM streams */
312 snd_pcm_suspend_all(i2sdev->sound.pcm);
313 /* Probably useless as we handle
314 * power transitions ourselves */
315 snd_power_change_state(i2sdev->sound.pcm->card,
316 SNDRV_CTL_POWER_D3hot);
317 }
318 /* Notify codecs */
319 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
320 err = 0;
321 if (cii->codec->suspend)
322 err = cii->codec->suspend(cii, state);
323 if (err)
324 ret = err;
325 }
326 }
327 return ret;
328}
329
330static int i2sbus_resume(struct macio_dev* dev)
331{
332 struct i2sbus_control *control = dev->ofdev.dev.driver_data;
333 struct codec_info_item *cii;
334 struct i2sbus_dev* i2sdev;
335 int err, ret = 0;
336
337 list_for_each_entry(i2sdev, &control->list, item) {
338 /* Notify codecs so they can re-initialize */
339 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
340 err = 0;
341 if (cii->codec->resume)
342 err = cii->codec->resume(cii);
343 if (err)
344 ret = err;
345 }
346 /* Notify Alsa */
347 if (i2sdev->sound.pcm) {
348 /* Same comment as above, probably useless */
349 snd_power_change_state(i2sdev->sound.pcm->card,
350 SNDRV_CTL_POWER_D0);
351 }
352 }
353
354 return ret;
355}
356#endif /* CONFIG_PM */
357
358static int i2sbus_shutdown(struct macio_dev* dev)
359{
360 return 0;
361}
362
363static struct macio_driver i2sbus_drv = {
364 .name = "soundbus-i2s",
365 .owner = THIS_MODULE,
366 .match_table = i2sbus_match,
367 .probe = i2sbus_probe,
368 .remove = i2sbus_remove,
369#ifdef CONFIG_PM
370 .suspend = i2sbus_suspend,
371 .resume = i2sbus_resume,
372#endif
373 .shutdown = i2sbus_shutdown,
374};
375
376static int __init soundbus_i2sbus_init(void)
377{
378 return macio_register_driver(&i2sbus_drv);
379}
380
381static void __exit soundbus_i2sbus_exit(void)
382{
383 macio_unregister_driver(&i2sbus_drv);
384}
385
386module_init(soundbus_i2sbus_init);
387module_exit(soundbus_i2sbus_exit);
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-interface.h b/sound/aoa/soundbus/i2sbus/i2sbus-interface.h
new file mode 100644
index 000000000000..c6b5f5452d20
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-interface.h
@@ -0,0 +1,187 @@
1/*
2 * i2sbus driver -- interface register definitions
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#ifndef __I2SBUS_INTERFACE_H
9#define __I2SBUS_INTERFACE_H
10
11/* i2s bus control registers, at least what we know about them */
12
13#define __PAD(m,n) u8 __pad##m[n]
14#define _PAD(line, n) __PAD(line, n)
15#define PAD(n) _PAD(__LINE__, (n))
16struct i2s_interface_regs {
17 __le32 intr_ctl; /* 0x00 */
18 PAD(12);
19 __le32 serial_format; /* 0x10 */
20 PAD(12);
21 __le32 codec_msg_out; /* 0x20 */
22 PAD(12);
23 __le32 codec_msg_in; /* 0x30 */
24 PAD(12);
25 __le32 frame_count; /* 0x40 */
26 PAD(12);
27 __le32 frame_match; /* 0x50 */
28 PAD(12);
29 __le32 data_word_sizes; /* 0x60 */
30 PAD(12);
31 __le32 peak_level_sel; /* 0x70 */
32 PAD(12);
33 __le32 peak_level_in0; /* 0x80 */
34 PAD(12);
35 __le32 peak_level_in1; /* 0x90 */
36 PAD(12);
37 /* total size: 0x100 bytes */
38} __attribute__((__packed__));
39
40/* interrupt register is just a bitfield with
41 * interrupt enable and pending bits */
42#define I2S_REG_INTR_CTL 0x00
43# define I2S_INT_FRAME_COUNT (1<<31)
44# define I2S_PENDING_FRAME_COUNT (1<<30)
45# define I2S_INT_MESSAGE_FLAG (1<<29)
46# define I2S_PENDING_MESSAGE_FLAG (1<<28)
47# define I2S_INT_NEW_PEAK (1<<27)
48# define I2S_PENDING_NEW_PEAK (1<<26)
49# define I2S_INT_CLOCKS_STOPPED (1<<25)
50# define I2S_PENDING_CLOCKS_STOPPED (1<<24)
51# define I2S_INT_EXTERNAL_SYNC_ERROR (1<<23)
52# define I2S_PENDING_EXTERNAL_SYNC_ERROR (1<<22)
53# define I2S_INT_EXTERNAL_SYNC_OK (1<<21)
54# define I2S_PENDING_EXTERNAL_SYNC_OK (1<<20)
55# define I2S_INT_NEW_SAMPLE_RATE (1<<19)
56# define I2S_PENDING_NEW_SAMPLE_RATE (1<<18)
57# define I2S_INT_STATUS_FLAG (1<<17)
58# define I2S_PENDING_STATUS_FLAG (1<<16)
59
60/* serial format register is more interesting :)
61 * It contains:
62 * - clock source
63 * - MClk divisor
64 * - SClk divisor
65 * - SClk master flag
66 * - serial format (sony, i2s 64x, i2s 32x, dav, silabs)
67 * - external sample frequency interrupt (don't understand)
68 * - external sample frequency
69 */
70#define I2S_REG_SERIAL_FORMAT 0x10
71/* clock source. You get either 18.432, 45.1584 or 49.1520 MHz */
72# define I2S_SF_CLOCK_SOURCE_SHIFT 30
73# define I2S_SF_CLOCK_SOURCE_MASK (3<<I2S_SF_CLOCK_SOURCE_SHIFT)
74# define I2S_SF_CLOCK_SOURCE_18MHz (0<<I2S_SF_CLOCK_SOURCE_SHIFT)
75# define I2S_SF_CLOCK_SOURCE_45MHz (1<<I2S_SF_CLOCK_SOURCE_SHIFT)
76# define I2S_SF_CLOCK_SOURCE_49MHz (2<<I2S_SF_CLOCK_SOURCE_SHIFT)
77/* also, let's define the exact clock speeds here, in Hz */
78#define I2S_CLOCK_SPEED_18MHz 18432000
79#define I2S_CLOCK_SPEED_45MHz 45158400
80#define I2S_CLOCK_SPEED_49MHz 49152000
81/* MClk is the clock that drives the codec, usually called its 'system clock'.
82 * It is derived by taking only every 'divisor' tick of the clock.
83 */
84# define I2S_SF_MCLKDIV_SHIFT 24
85# define I2S_SF_MCLKDIV_MASK (0x1F<<I2S_SF_MCLKDIV_SHIFT)
86# define I2S_SF_MCLKDIV_1 (0x14<<I2S_SF_MCLKDIV_SHIFT)
87# define I2S_SF_MCLKDIV_3 (0x13<<I2S_SF_MCLKDIV_SHIFT)
88# define I2S_SF_MCLKDIV_5 (0x12<<I2S_SF_MCLKDIV_SHIFT)
89# define I2S_SF_MCLKDIV_14 (0x0E<<I2S_SF_MCLKDIV_SHIFT)
90# define I2S_SF_MCLKDIV_OTHER(div) (((div/2-1)<<I2S_SF_MCLKDIV_SHIFT)&I2S_SF_MCLKDIV_MASK)
91static inline int i2s_sf_mclkdiv(int div, int *out)
92{
93 int d;
94
95 switch(div) {
96 case 1: *out |= I2S_SF_MCLKDIV_1; return 0;
97 case 3: *out |= I2S_SF_MCLKDIV_3; return 0;
98 case 5: *out |= I2S_SF_MCLKDIV_5; return 0;
99 case 14: *out |= I2S_SF_MCLKDIV_14; return 0;
100 default:
101 if (div%2) return -1;
102 d = div/2-1;
103 if (d == 0x14 || d == 0x13 || d == 0x12 || d == 0x0E)
104 return -1;
105 *out |= I2S_SF_MCLKDIV_OTHER(div);
106 return 0;
107 }
108}
109/* SClk is the clock that drives the i2s wire bus. Note that it is
110 * derived from the MClk above by taking only every 'divisor' tick
111 * of MClk.
112 */
113# define I2S_SF_SCLKDIV_SHIFT 20
114# define I2S_SF_SCLKDIV_MASK (0xF<<I2S_SF_SCLKDIV_SHIFT)
115# define I2S_SF_SCLKDIV_1 (8<<I2S_SF_SCLKDIV_SHIFT)
116# define I2S_SF_SCLKDIV_3 (9<<I2S_SF_SCLKDIV_SHIFT)
117# define I2S_SF_SCLKDIV_OTHER(div) (((div/2-1)<<I2S_SF_SCLKDIV_SHIFT)&I2S_SF_SCLKDIV_MASK)
118static inline int i2s_sf_sclkdiv(int div, int *out)
119{
120 int d;
121
122 switch(div) {
123 case 1: *out |= I2S_SF_SCLKDIV_1; return 0;
124 case 3: *out |= I2S_SF_SCLKDIV_3; return 0;
125 default:
126 if (div%2) return -1;
127 d = div/2-1;
128 if (d == 8 || d == 9) return -1;
129 *out |= I2S_SF_SCLKDIV_OTHER(div);
130 return 0;
131 }
132}
133# define I2S_SF_SCLK_MASTER (1<<19)
134/* serial format is the way the data is put to the i2s wire bus */
135# define I2S_SF_SERIAL_FORMAT_SHIFT 16
136# define I2S_SF_SERIAL_FORMAT_MASK (7<<I2S_SF_SERIAL_FORMAT_SHIFT)
137# define I2S_SF_SERIAL_FORMAT_SONY (0<<I2S_SF_SERIAL_FORMAT_SHIFT)
138# define I2S_SF_SERIAL_FORMAT_I2S_64X (1<<I2S_SF_SERIAL_FORMAT_SHIFT)
139# define I2S_SF_SERIAL_FORMAT_I2S_32X (2<<I2S_SF_SERIAL_FORMAT_SHIFT)
140# define I2S_SF_SERIAL_FORMAT_I2S_DAV (4<<I2S_SF_SERIAL_FORMAT_SHIFT)
141# define I2S_SF_SERIAL_FORMAT_I2S_SILABS (5<<I2S_SF_SERIAL_FORMAT_SHIFT)
142/* unknown */
143# define I2S_SF_EXT_SAMPLE_FREQ_INT_SHIFT 12
144# define I2S_SF_EXT_SAMPLE_FREQ_INT_MASK (0xF<<I2S_SF_SAMPLE_FREQ_INT_SHIFT)
145/* probably gives external frequency? */
146# define I2S_SF_EXT_SAMPLE_FREQ_MASK 0xFFF
147
148/* used to send codec messages, but how isn't clear */
149#define I2S_REG_CODEC_MSG_OUT 0x20
150
151/* used to receive codec messages, but how isn't clear */
152#define I2S_REG_CODEC_MSG_IN 0x30
153
154/* frame count reg isn't clear to me yet, but probably useful */
155#define I2S_REG_FRAME_COUNT 0x40
156
157/* program to some value, and get interrupt if frame count reaches it */
158#define I2S_REG_FRAME_MATCH 0x50
159
160/* this register describes how the bus transfers data */
161#define I2S_REG_DATA_WORD_SIZES 0x60
162/* number of interleaved input channels */
163# define I2S_DWS_NUM_CHANNELS_IN_SHIFT 24
164# define I2S_DWS_NUM_CHANNELS_IN_MASK (0x1F<<I2S_DWS_NUM_CHANNELS_IN_SHIFT)
165/* word size of input data */
166# define I2S_DWS_DATA_IN_SIZE_SHIFT 16
167# define I2S_DWS_DATA_IN_16BIT (0<<I2S_DWS_DATA_IN_SIZE_SHIFT)
168# define I2S_DWS_DATA_IN_24BIT (3<<I2S_DWS_DATA_IN_SIZE_SHIFT)
169/* number of interleaved output channels */
170# define I2S_DWS_NUM_CHANNELS_OUT_SHIFT 8
171# define I2S_DWS_NUM_CHANNELS_OUT_MASK (0x1F<<I2S_DWS_NUM_CHANNELS_OUT_SHIFT)
172/* word size of output data */
173# define I2S_DWS_DATA_OUT_SIZE_SHIFT 0
174# define I2S_DWS_DATA_OUT_16BIT (0<<I2S_DWS_DATA_OUT_SIZE_SHIFT)
175# define I2S_DWS_DATA_OUT_24BIT (3<<I2S_DWS_DATA_OUT_SIZE_SHIFT)
176
177
178/* unknown */
179#define I2S_REG_PEAK_LEVEL_SEL 0x70
180
181/* unknown */
182#define I2S_REG_PEAK_LEVEL_IN0 0x80
183
184/* unknown */
185#define I2S_REG_PEAK_LEVEL_IN1 0x90
186
187#endif /* __I2SBUS_INTERFACE_H */
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c b/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c
new file mode 100644
index 000000000000..3049015a04f1
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c
@@ -0,0 +1,1021 @@
1/*
2 * i2sbus driver -- pcm routines
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#include <asm/io.h>
10#include <linux/delay.h>
11/* So apparently there's a reason for requiring driver.h
12 * to be included first, even if I don't know it... */
13#include <sound/driver.h>
14#include <sound/core.h>
15#include <asm/macio.h>
16#include <linux/pci.h>
17#include "../soundbus.h"
18#include "i2sbus.h"
19
20static inline void get_pcm_info(struct i2sbus_dev *i2sdev, int in,
21 struct pcm_info **pi, struct pcm_info **other)
22{
23 if (in) {
24 if (pi)
25 *pi = &i2sdev->in;
26 if (other)
27 *other = &i2sdev->out;
28 } else {
29 if (pi)
30 *pi = &i2sdev->out;
31 if (other)
32 *other = &i2sdev->in;
33 }
34}
35
36static int clock_and_divisors(int mclk, int sclk, int rate, int *out)
37{
38 /* sclk must be derived from mclk! */
39 if (mclk % sclk)
40 return -1;
41 /* derive sclk register value */
42 if (i2s_sf_sclkdiv(mclk / sclk, out))
43 return -1;
44
45 if (I2S_CLOCK_SPEED_18MHz % (rate * mclk) == 0) {
46 if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_18MHz / (rate * mclk), out)) {
47 *out |= I2S_SF_CLOCK_SOURCE_18MHz;
48 return 0;
49 }
50 }
51 if (I2S_CLOCK_SPEED_45MHz % (rate * mclk) == 0) {
52 if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_45MHz / (rate * mclk), out)) {
53 *out |= I2S_SF_CLOCK_SOURCE_45MHz;
54 return 0;
55 }
56 }
57 if (I2S_CLOCK_SPEED_49MHz % (rate * mclk) == 0) {
58 if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_49MHz / (rate * mclk), out)) {
59 *out |= I2S_SF_CLOCK_SOURCE_49MHz;
60 return 0;
61 }
62 }
63 return -1;
64}
65
66#define CHECK_RATE(rate) \
67 do { if (rates & SNDRV_PCM_RATE_ ##rate) { \
68 int dummy; \
69 if (clock_and_divisors(sysclock_factor, \
70 bus_factor, rate, &dummy)) \
71 rates &= ~SNDRV_PCM_RATE_ ##rate; \
72 } } while (0)
73
74static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
75{
76 struct pcm_info *pi, *other;
77 struct soundbus_dev *sdev;
78 int masks_inited = 0, err;
79 struct codec_info_item *cii, *rev;
80 struct snd_pcm_hardware *hw;
81 u64 formats = 0;
82 unsigned int rates = 0;
83 struct transfer_info v;
84 int result = 0;
85 int bus_factor = 0, sysclock_factor = 0;
86 int found_this;
87
88 mutex_lock(&i2sdev->lock);
89
90 get_pcm_info(i2sdev, in, &pi, &other);
91
92 hw = &pi->substream->runtime->hw;
93 sdev = &i2sdev->sound;
94
95 if (pi->active) {
96 /* alsa messed up */
97 result = -EBUSY;
98 goto out_unlock;
99 }
100
101 /* we now need to assign the hw */
102 list_for_each_entry(cii, &sdev->codec_list, list) {
103 struct transfer_info *ti = cii->codec->transfers;
104 bus_factor = cii->codec->bus_factor;
105 sysclock_factor = cii->codec->sysclock_factor;
106 while (ti->formats && ti->rates) {
107 v = *ti;
108 if (ti->transfer_in == in
109 && cii->codec->usable(cii, ti, &v)) {
110 if (masks_inited) {
111 formats &= v.formats;
112 rates &= v.rates;
113 } else {
114 formats = v.formats;
115 rates = v.rates;
116 masks_inited = 1;
117 }
118 }
119 ti++;
120 }
121 }
122 if (!masks_inited || !bus_factor || !sysclock_factor) {
123 result = -ENODEV;
124 goto out_unlock;
125 }
126 /* bus dependent stuff */
127 hw->info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
128 SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME;
129
130 CHECK_RATE(5512);
131 CHECK_RATE(8000);
132 CHECK_RATE(11025);
133 CHECK_RATE(16000);
134 CHECK_RATE(22050);
135 CHECK_RATE(32000);
136 CHECK_RATE(44100);
137 CHECK_RATE(48000);
138 CHECK_RATE(64000);
139 CHECK_RATE(88200);
140 CHECK_RATE(96000);
141 CHECK_RATE(176400);
142 CHECK_RATE(192000);
143 hw->rates = rates;
144
145 /* well. the codec might want 24 bits only, and we'll
146 * ever only transfer 24 bits, but they are top-aligned!
147 * So for alsa, we claim that we're doing full 32 bit
148 * while in reality we'll ignore the lower 8 bits of
149 * that when doing playback (they're transferred as 0
150 * as far as I know, no codecs we have are 32-bit capable
151 * so I can't really test) and when doing recording we'll
152 * always have those lower 8 bits recorded as 0 */
153 if (formats & SNDRV_PCM_FMTBIT_S24_BE)
154 formats |= SNDRV_PCM_FMTBIT_S32_BE;
155 if (formats & SNDRV_PCM_FMTBIT_U24_BE)
156 formats |= SNDRV_PCM_FMTBIT_U32_BE;
157 /* now mask off what we can support. I suppose we could
158 * also support S24_3LE and some similar formats, but I
159 * doubt there's a codec that would be able to use that,
160 * so we don't support it here. */
161 hw->formats = formats & (SNDRV_PCM_FMTBIT_S16_BE |
162 SNDRV_PCM_FMTBIT_U16_BE |
163 SNDRV_PCM_FMTBIT_S32_BE |
164 SNDRV_PCM_FMTBIT_U32_BE);
165
166 /* we need to set the highest and lowest rate possible.
167 * These are the highest and lowest rates alsa can
168 * support properly in its bitfield.
169 * Below, we'll use that to restrict to the rate
170 * currently in use (if any). */
171 hw->rate_min = 5512;
172 hw->rate_max = 192000;
173 /* if the other stream is active, then we can only
174 * support what it is currently using.
175 * FIXME: I lied. This comment is wrong. We can support
176 * anything that works with the same serial format, ie.
177 * when recording 24 bit sound we can well play 16 bit
178 * sound at the same time iff using the same transfer mode.
179 */
180 if (other->active) {
181 /* FIXME: is this guaranteed by the alsa api? */
182 hw->formats &= (1ULL << i2sdev->format);
183 /* see above, restrict rates to the one we already have */
184 hw->rate_min = i2sdev->rate;
185 hw->rate_max = i2sdev->rate;
186 }
187
188 hw->channels_min = 2;
189 hw->channels_max = 2;
190 /* these are somewhat arbitrary */
191 hw->buffer_bytes_max = 131072;
192 hw->period_bytes_min = 256;
193 hw->period_bytes_max = 16384;
194 hw->periods_min = 3;
195 hw->periods_max = MAX_DBDMA_COMMANDS;
196 list_for_each_entry(cii, &sdev->codec_list, list) {
197 if (cii->codec->open) {
198 err = cii->codec->open(cii, pi->substream);
199 if (err) {
200 result = err;
201 /* unwind */
202 found_this = 0;
203 list_for_each_entry_reverse(rev,
204 &sdev->codec_list, list) {
205 if (found_this && rev->codec->close) {
206 rev->codec->close(rev,
207 pi->substream);
208 }
209 if (rev == cii)
210 found_this = 1;
211 }
212 goto out_unlock;
213 }
214 }
215 }
216
217 out_unlock:
218 mutex_unlock(&i2sdev->lock);
219 return result;
220}
221
222#undef CHECK_RATE
223
224static int i2sbus_pcm_close(struct i2sbus_dev *i2sdev, int in)
225{
226 struct codec_info_item *cii;
227 struct pcm_info *pi;
228 int err = 0, tmp;
229
230 mutex_lock(&i2sdev->lock);
231
232 get_pcm_info(i2sdev, in, &pi, NULL);
233
234 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
235 if (cii->codec->close) {
236 tmp = cii->codec->close(cii, pi->substream);
237 if (tmp)
238 err = tmp;
239 }
240 }
241
242 pi->substream = NULL;
243 pi->active = 0;
244 mutex_unlock(&i2sdev->lock);
245 return err;
246}
247
248static int i2sbus_hw_params(struct snd_pcm_substream *substream,
249 struct snd_pcm_hw_params *params)
250{
251 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
252}
253
254static int i2sbus_hw_free(struct snd_pcm_substream *substream)
255{
256 snd_pcm_lib_free_pages(substream);
257 return 0;
258}
259
260static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
261{
262 /* whee. Hard work now. The user has selected a bitrate
263 * and bit format, so now we have to program our
264 * I2S controller appropriately. */
265 struct snd_pcm_runtime *runtime;
266 struct dbdma_cmd *command;
267 int i, periodsize;
268 dma_addr_t offset;
269 struct bus_info bi;
270 struct codec_info_item *cii;
271 int sfr = 0; /* serial format register */
272 int dws = 0; /* data word sizes reg */
273 int input_16bit;
274 struct pcm_info *pi, *other;
275 int cnt;
276 int result = 0;
277
278 mutex_lock(&i2sdev->lock);
279
280 get_pcm_info(i2sdev, in, &pi, &other);
281
282 if (pi->dbdma_ring.running) {
283 result = -EBUSY;
284 goto out_unlock;
285 }
286
287 runtime = pi->substream->runtime;
288 pi->active = 1;
289 if (other->active &&
290 ((i2sdev->format != runtime->format)
291 || (i2sdev->rate != runtime->rate))) {
292 result = -EINVAL;
293 goto out_unlock;
294 }
295
296 i2sdev->format = runtime->format;
297 i2sdev->rate = runtime->rate;
298
299 periodsize = snd_pcm_lib_period_bytes(pi->substream);
300 pi->current_period = 0;
301
302 /* generate dbdma command ring first */
303 command = pi->dbdma_ring.cmds;
304 offset = runtime->dma_addr;
305 for (i = 0; i < pi->substream->runtime->periods;
306 i++, command++, offset += periodsize) {
307 memset(command, 0, sizeof(struct dbdma_cmd));
308 command->command =
309 cpu_to_le16((in ? INPUT_MORE : OUTPUT_MORE) | INTR_ALWAYS);
310 command->phy_addr = cpu_to_le32(offset);
311 command->req_count = cpu_to_le16(periodsize);
312 command->xfer_status = cpu_to_le16(0);
313 }
314 /* last one branches back to first */
315 command--;
316 command->command |= cpu_to_le16(BR_ALWAYS);
317 command->cmd_dep = cpu_to_le32(pi->dbdma_ring.bus_cmd_start);
318
319 /* ok, let's set the serial format and stuff */
320 switch (runtime->format) {
321 /* 16 bit formats */
322 case SNDRV_PCM_FORMAT_S16_BE:
323 case SNDRV_PCM_FORMAT_U16_BE:
324 /* FIXME: if we add different bus factors we need to
325 * do more here!! */
326 bi.bus_factor = 0;
327 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
328 bi.bus_factor = cii->codec->bus_factor;
329 break;
330 }
331 if (!bi.bus_factor) {
332 result = -ENODEV;
333 goto out_unlock;
334 }
335 input_16bit = 1;
336 break;
337 case SNDRV_PCM_FORMAT_S32_BE:
338 case SNDRV_PCM_FORMAT_U32_BE:
339 /* force 64x bus speed, otherwise the data cannot be
340 * transferred quickly enough! */
341 bi.bus_factor = 64;
342 input_16bit = 0;
343 break;
344 default:
345 result = -EINVAL;
346 goto out_unlock;
347 }
348 /* we assume all sysclocks are the same! */
349 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
350 bi.sysclock_factor = cii->codec->sysclock_factor;
351 break;
352 }
353
354 if (clock_and_divisors(bi.sysclock_factor,
355 bi.bus_factor,
356 runtime->rate,
357 &sfr) < 0) {
358 result = -EINVAL;
359 goto out_unlock;
360 }
361 switch (bi.bus_factor) {
362 case 32:
363 sfr |= I2S_SF_SERIAL_FORMAT_I2S_32X;
364 break;
365 case 64:
366 sfr |= I2S_SF_SERIAL_FORMAT_I2S_64X;
367 break;
368 }
369 /* FIXME: THIS ASSUMES MASTER ALL THE TIME */
370 sfr |= I2S_SF_SCLK_MASTER;
371
372 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
373 int err = 0;
374 if (cii->codec->prepare)
375 err = cii->codec->prepare(cii, &bi, pi->substream);
376 if (err) {
377 result = err;
378 goto out_unlock;
379 }
380 }
381 /* codecs are fine with it, so set our clocks */
382 if (input_16bit)
383 dws = (2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
384 (2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
385 I2S_DWS_DATA_IN_16BIT | I2S_DWS_DATA_OUT_16BIT;
386 else
387 dws = (2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
388 (2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
389 I2S_DWS_DATA_IN_24BIT | I2S_DWS_DATA_OUT_24BIT;
390
391 /* early exit if already programmed correctly */
392 /* not locking these is fine since we touch them only in this function */
393 if (in_le32(&i2sdev->intfregs->serial_format) == sfr
394 && in_le32(&i2sdev->intfregs->data_word_sizes) == dws)
395 goto out_unlock;
396
397 /* let's notify the codecs about clocks going away.
398 * For now we only do mastering on the i2s cell... */
399 list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
400 if (cii->codec->switch_clock)
401 cii->codec->switch_clock(cii, CLOCK_SWITCH_PREPARE_SLAVE);
402
403 i2sbus_control_enable(i2sdev->control, i2sdev);
404 i2sbus_control_cell(i2sdev->control, i2sdev, 1);
405
406 out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);
407
408 i2sbus_control_clock(i2sdev->control, i2sdev, 0);
409
410 msleep(1);
411
412 /* wait for clock stopped. This can apparently take a while... */
413 cnt = 100;
414 while (cnt-- &&
415 !(in_le32(&i2sdev->intfregs->intr_ctl) & I2S_PENDING_CLOCKS_STOPPED)) {
416 msleep(5);
417 }
418 out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);
419
420 /* not locking these is fine since we touch them only in this function */
421 out_le32(&i2sdev->intfregs->serial_format, sfr);
422 out_le32(&i2sdev->intfregs->data_word_sizes, dws);
423
424 i2sbus_control_enable(i2sdev->control, i2sdev);
425 i2sbus_control_cell(i2sdev->control, i2sdev, 1);
426 i2sbus_control_clock(i2sdev->control, i2sdev, 1);
427 msleep(1);
428
429 list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
430 if (cii->codec->switch_clock)
431 cii->codec->switch_clock(cii, CLOCK_SWITCH_SLAVE);
432
433 out_unlock:
434 mutex_unlock(&i2sdev->lock);
435 return result;
436}
437
438static struct dbdma_cmd STOP_CMD = {
439 .command = __constant_cpu_to_le16(DBDMA_STOP),
440};
441
442static int i2sbus_pcm_trigger(struct i2sbus_dev *i2sdev, int in, int cmd)
443{
444 struct codec_info_item *cii;
445 struct pcm_info *pi;
446 int timeout;
447 struct dbdma_cmd tmp;
448 int result = 0;
449 unsigned long flags;
450
451 spin_lock_irqsave(&i2sdev->low_lock, flags);
452
453 get_pcm_info(i2sdev, in, &pi, NULL);
454
455 switch (cmd) {
456 case SNDRV_PCM_TRIGGER_START:
457 case SNDRV_PCM_TRIGGER_RESUME:
458 if (pi->dbdma_ring.running) {
459 result = -EALREADY;
460 goto out_unlock;
461 }
462 list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
463 if (cii->codec->start)
464 cii->codec->start(cii, pi->substream);
465 pi->dbdma_ring.running = 1;
466
467 /* reset dma engine */
468 out_le32(&pi->dbdma->control,
469 0 | (RUN | PAUSE | FLUSH | WAKE) << 16);
470 timeout = 100;
471 while (in_le32(&pi->dbdma->status) & RUN && timeout--)
472 udelay(1);
473 if (timeout <= 0) {
474 printk(KERN_ERR
475 "i2sbus: error waiting for dma reset\n");
476 result = -ENXIO;
477 goto out_unlock;
478 }
479
480 /* write dma command buffer address to the dbdma chip */
481 out_le32(&pi->dbdma->cmdptr, pi->dbdma_ring.bus_cmd_start);
482 /* post PCI write */
483 mb();
484 (void)in_le32(&pi->dbdma->status);
485
486 /* change first command to STOP */
487 tmp = *pi->dbdma_ring.cmds;
488 *pi->dbdma_ring.cmds = STOP_CMD;
489
490 /* set running state, remember that the first command is STOP */
491 out_le32(&pi->dbdma->control, RUN | (RUN << 16));
492 timeout = 100;
493 /* wait for STOP to be executed */
494 while (in_le32(&pi->dbdma->status) & ACTIVE && timeout--)
495 udelay(1);
496 if (timeout <= 0) {
497 printk(KERN_ERR "i2sbus: error waiting for dma stop\n");
498 result = -ENXIO;
499 goto out_unlock;
500 }
501 /* again, write dma command buffer address to the dbdma chip,
502 * this time of the first real command */
503 *pi->dbdma_ring.cmds = tmp;
504 out_le32(&pi->dbdma->cmdptr, pi->dbdma_ring.bus_cmd_start);
505 /* post write */
506 mb();
507 (void)in_le32(&pi->dbdma->status);
508
509 /* reset dma engine again */
510 out_le32(&pi->dbdma->control,
511 0 | (RUN | PAUSE | FLUSH | WAKE) << 16);
512 timeout = 100;
513 while (in_le32(&pi->dbdma->status) & RUN && timeout--)
514 udelay(1);
515 if (timeout <= 0) {
516 printk(KERN_ERR
517 "i2sbus: error waiting for dma reset\n");
518 result = -ENXIO;
519 goto out_unlock;
520 }
521
522 /* wake up the chip with the next descriptor */
523 out_le32(&pi->dbdma->control,
524 (RUN | WAKE) | ((RUN | WAKE) << 16));
525 /* get the frame count */
526 pi->frame_count = in_le32(&i2sdev->intfregs->frame_count);
527
528 /* off you go! */
529 break;
530 case SNDRV_PCM_TRIGGER_STOP:
531 case SNDRV_PCM_TRIGGER_SUSPEND:
532 if (!pi->dbdma_ring.running) {
533 result = -EALREADY;
534 goto out_unlock;
535 }
536
537 /* turn off all relevant bits */
538 out_le32(&pi->dbdma->control,
539 (RUN | WAKE | FLUSH | PAUSE) << 16);
540 {
541 /* FIXME: move to own function */
542 int timeout = 5000;
543 while ((in_le32(&pi->dbdma->status) & RUN)
544 && --timeout > 0)
545 udelay(1);
546 if (!timeout)
547 printk(KERN_ERR
548 "i2sbus: timed out turning "
549 "off dbdma engine!\n");
550 }
551
552 pi->dbdma_ring.running = 0;
553 list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
554 if (cii->codec->stop)
555 cii->codec->stop(cii, pi->substream);
556 break;
557 default:
558 result = -EINVAL;
559 goto out_unlock;
560 }
561
562 out_unlock:
563 spin_unlock_irqrestore(&i2sdev->low_lock, flags);
564 return result;
565}
566
567static snd_pcm_uframes_t i2sbus_pcm_pointer(struct i2sbus_dev *i2sdev, int in)
568{
569 struct pcm_info *pi;
570 u32 fc;
571
572 get_pcm_info(i2sdev, in, &pi, NULL);
573
574 fc = in_le32(&i2sdev->intfregs->frame_count);
575 fc = fc - pi->frame_count;
576
577 return (bytes_to_frames(pi->substream->runtime,
578 pi->current_period *
579 snd_pcm_lib_period_bytes(pi->substream))
580 + fc) % pi->substream->runtime->buffer_size;
581}
582
583static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in)
584{
585 struct pcm_info *pi;
586 u32 fc;
587 u32 delta;
588
589 spin_lock(&i2sdev->low_lock);
590 get_pcm_info(i2sdev, in, &pi, NULL);
591
592 if (!pi->dbdma_ring.running) {
593 /* there was still an interrupt pending
594 * while we stopped. or maybe another
595 * processor (not the one that was stopping
596 * the DMA engine) was spinning above
597 * waiting for the lock. */
598 goto out_unlock;
599 }
600
601 fc = in_le32(&i2sdev->intfregs->frame_count);
602 /* a counter overflow does not change the calculation. */
603 delta = fc - pi->frame_count;
604
605 /* update current_period */
606 while (delta >= pi->substream->runtime->period_size) {
607 pi->current_period++;
608 delta = delta - pi->substream->runtime->period_size;
609 }
610
611 if (unlikely(delta)) {
612 /* Some interrupt came late, so check the dbdma.
613 * This special case exists to syncronize the frame_count with
614 * the dbdma transfer, but is hit every once in a while. */
615 int period;
616
617 period = (in_le32(&pi->dbdma->cmdptr)
618 - pi->dbdma_ring.bus_cmd_start)
619 / sizeof(struct dbdma_cmd);
620 pi->current_period = pi->current_period
621 % pi->substream->runtime->periods;
622
623 while (pi->current_period != period) {
624 pi->current_period++;
625 pi->current_period %= pi->substream->runtime->periods;
626 /* Set delta to zero, as the frame_count value is too
627 * high (otherwise the code path will not be executed).
628 * This corrects the fact that the frame_count is too
629 * low at the beginning due to buffering. */
630 delta = 0;
631 }
632 }
633
634 pi->frame_count = fc - delta;
635 pi->current_period %= pi->substream->runtime->periods;
636
637 spin_unlock(&i2sdev->low_lock);
638 /* may call _trigger again, hence needs to be unlocked */
639 snd_pcm_period_elapsed(pi->substream);
640 return;
641 out_unlock:
642 spin_unlock(&i2sdev->low_lock);
643}
644
645irqreturn_t i2sbus_tx_intr(int irq, void *devid, struct pt_regs *regs)
646{
647 handle_interrupt((struct i2sbus_dev *)devid, 0);
648 return IRQ_HANDLED;
649}
650
651irqreturn_t i2sbus_rx_intr(int irq, void *devid, struct pt_regs * regs)
652{
653 handle_interrupt((struct i2sbus_dev *)devid, 1);
654 return IRQ_HANDLED;
655}
656
657static int i2sbus_playback_open(struct snd_pcm_substream *substream)
658{
659 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
660
661 if (!i2sdev)
662 return -EINVAL;
663 i2sdev->out.substream = substream;
664 return i2sbus_pcm_open(i2sdev, 0);
665}
666
667static int i2sbus_playback_close(struct snd_pcm_substream *substream)
668{
669 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
670 int err;
671
672 if (!i2sdev)
673 return -EINVAL;
674 if (i2sdev->out.substream != substream)
675 return -EINVAL;
676 err = i2sbus_pcm_close(i2sdev, 0);
677 if (!err)
678 i2sdev->out.substream = NULL;
679 return err;
680}
681
682static int i2sbus_playback_prepare(struct snd_pcm_substream *substream)
683{
684 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
685
686 if (!i2sdev)
687 return -EINVAL;
688 if (i2sdev->out.substream != substream)
689 return -EINVAL;
690 return i2sbus_pcm_prepare(i2sdev, 0);
691}
692
693static int i2sbus_playback_trigger(struct snd_pcm_substream *substream, int cmd)
694{
695 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
696
697 if (!i2sdev)
698 return -EINVAL;
699 if (i2sdev->out.substream != substream)
700 return -EINVAL;
701 return i2sbus_pcm_trigger(i2sdev, 0, cmd);
702}
703
704static snd_pcm_uframes_t i2sbus_playback_pointer(struct snd_pcm_substream
705 *substream)
706{
707 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
708
709 if (!i2sdev)
710 return -EINVAL;
711 if (i2sdev->out.substream != substream)
712 return 0;
713 return i2sbus_pcm_pointer(i2sdev, 0);
714}
715
716static struct snd_pcm_ops i2sbus_playback_ops = {
717 .open = i2sbus_playback_open,
718 .close = i2sbus_playback_close,
719 .ioctl = snd_pcm_lib_ioctl,
720 .hw_params = i2sbus_hw_params,
721 .hw_free = i2sbus_hw_free,
722 .prepare = i2sbus_playback_prepare,
723 .trigger = i2sbus_playback_trigger,
724 .pointer = i2sbus_playback_pointer,
725};
726
727static int i2sbus_record_open(struct snd_pcm_substream *substream)
728{
729 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
730
731 if (!i2sdev)
732 return -EINVAL;
733 i2sdev->in.substream = substream;
734 return i2sbus_pcm_open(i2sdev, 1);
735}
736
737static int i2sbus_record_close(struct snd_pcm_substream *substream)
738{
739 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
740 int err;
741
742 if (!i2sdev)
743 return -EINVAL;
744 if (i2sdev->in.substream != substream)
745 return -EINVAL;
746 err = i2sbus_pcm_close(i2sdev, 1);
747 if (!err)
748 i2sdev->in.substream = NULL;
749 return err;
750}
751
752static int i2sbus_record_prepare(struct snd_pcm_substream *substream)
753{
754 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
755
756 if (!i2sdev)
757 return -EINVAL;
758 if (i2sdev->in.substream != substream)
759 return -EINVAL;
760 return i2sbus_pcm_prepare(i2sdev, 1);
761}
762
763static int i2sbus_record_trigger(struct snd_pcm_substream *substream, int cmd)
764{
765 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
766
767 if (!i2sdev)
768 return -EINVAL;
769 if (i2sdev->in.substream != substream)
770 return -EINVAL;
771 return i2sbus_pcm_trigger(i2sdev, 1, cmd);
772}
773
774static snd_pcm_uframes_t i2sbus_record_pointer(struct snd_pcm_substream
775 *substream)
776{
777 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
778
779 if (!i2sdev)
780 return -EINVAL;
781 if (i2sdev->in.substream != substream)
782 return 0;
783 return i2sbus_pcm_pointer(i2sdev, 1);
784}
785
786static struct snd_pcm_ops i2sbus_record_ops = {
787 .open = i2sbus_record_open,
788 .close = i2sbus_record_close,
789 .ioctl = snd_pcm_lib_ioctl,
790 .hw_params = i2sbus_hw_params,
791 .hw_free = i2sbus_hw_free,
792 .prepare = i2sbus_record_prepare,
793 .trigger = i2sbus_record_trigger,
794 .pointer = i2sbus_record_pointer,
795};
796
797static void i2sbus_private_free(struct snd_pcm *pcm)
798{
799 struct i2sbus_dev *i2sdev = snd_pcm_chip(pcm);
800 struct codec_info_item *p, *tmp;
801
802 i2sdev->sound.pcm = NULL;
803 i2sdev->out.created = 0;
804 i2sdev->in.created = 0;
805 list_for_each_entry_safe(p, tmp, &i2sdev->sound.codec_list, list) {
806 printk(KERN_ERR "i2sbus: a codec didn't unregister!\n");
807 list_del(&p->list);
808 module_put(p->codec->owner);
809 kfree(p);
810 }
811 soundbus_dev_put(&i2sdev->sound);
812 module_put(THIS_MODULE);
813}
814
815/* FIXME: this function needs an error handling strategy with labels */
816int
817i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
818 struct codec_info *ci, void *data)
819{
820 int err, in = 0, out = 0;
821 struct transfer_info *tmp;
822 struct i2sbus_dev *i2sdev = soundbus_dev_to_i2sbus_dev(dev);
823 struct codec_info_item *cii;
824
825 if (!dev->pcmname || dev->pcmid == -1) {
826 printk(KERN_ERR "i2sbus: pcm name and id must be set!\n");
827 return -EINVAL;
828 }
829
830 list_for_each_entry(cii, &dev->codec_list, list) {
831 if (cii->codec_data == data)
832 return -EALREADY;
833 }
834
835 if (!ci->transfers || !ci->transfers->formats
836 || !ci->transfers->rates || !ci->usable)
837 return -EINVAL;
838
839 /* we currently code the i2s transfer on the clock, and support only
840 * 32 and 64 */
841 if (ci->bus_factor != 32 && ci->bus_factor != 64)
842 return -EINVAL;
843
844 /* If you want to fix this, you need to keep track of what transport infos
845 * are to be used, which codecs they belong to, and then fix all the
846 * sysclock/busclock stuff above to depend on which is usable */
847 list_for_each_entry(cii, &dev->codec_list, list) {
848 if (cii->codec->sysclock_factor != ci->sysclock_factor) {
849 printk(KERN_DEBUG
850 "cannot yet handle multiple different sysclocks!\n");
851 return -EINVAL;
852 }
853 if (cii->codec->bus_factor != ci->bus_factor) {
854 printk(KERN_DEBUG
855 "cannot yet handle multiple different bus clocks!\n");
856 return -EINVAL;
857 }
858 }
859
860 tmp = ci->transfers;
861 while (tmp->formats && tmp->rates) {
862 if (tmp->transfer_in)
863 in = 1;
864 else
865 out = 1;
866 tmp++;
867 }
868
869 cii = kzalloc(sizeof(struct codec_info_item), GFP_KERNEL);
870 if (!cii) {
871 printk(KERN_DEBUG "i2sbus: failed to allocate cii\n");
872 return -ENOMEM;
873 }
874
875 /* use the private data to point to the codec info */
876 cii->sdev = soundbus_dev_get(dev);
877 cii->codec = ci;
878 cii->codec_data = data;
879
880 if (!cii->sdev) {
881 printk(KERN_DEBUG
882 "i2sbus: failed to get soundbus dev reference\n");
883 kfree(cii);
884 return -ENODEV;
885 }
886
887 if (!try_module_get(THIS_MODULE)) {
888 printk(KERN_DEBUG "i2sbus: failed to get module reference!\n");
889 soundbus_dev_put(dev);
890 kfree(cii);
891 return -EBUSY;
892 }
893
894 if (!try_module_get(ci->owner)) {
895 printk(KERN_DEBUG
896 "i2sbus: failed to get module reference to codec owner!\n");
897 module_put(THIS_MODULE);
898 soundbus_dev_put(dev);
899 kfree(cii);
900 return -EBUSY;
901 }
902
903 if (!dev->pcm) {
904 err = snd_pcm_new(card,
905 dev->pcmname,
906 dev->pcmid,
907 0,
908 0,
909 &dev->pcm);
910 if (err) {
911 printk(KERN_DEBUG "i2sbus: failed to create pcm\n");
912 kfree(cii);
913 module_put(ci->owner);
914 soundbus_dev_put(dev);
915 module_put(THIS_MODULE);
916 return err;
917 }
918 }
919
920 /* ALSA yet again sucks.
921 * If it is ever fixed, remove this line. See below. */
922 out = in = 1;
923
924 if (!i2sdev->out.created && out) {
925 if (dev->pcm->card != card) {
926 /* eh? */
927 printk(KERN_ERR
928 "Can't attach same bus to different cards!\n");
929 module_put(ci->owner);
930 kfree(cii);
931 soundbus_dev_put(dev);
932 module_put(THIS_MODULE);
933 return -EINVAL;
934 }
935 if ((err =
936 snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, 1))) {
937 module_put(ci->owner);
938 kfree(cii);
939 soundbus_dev_put(dev);
940 module_put(THIS_MODULE);
941 return err;
942 }
943 snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
944 &i2sbus_playback_ops);
945 i2sdev->out.created = 1;
946 }
947
948 if (!i2sdev->in.created && in) {
949 if (dev->pcm->card != card) {
950 printk(KERN_ERR
951 "Can't attach same bus to different cards!\n");
952 module_put(ci->owner);
953 kfree(cii);
954 soundbus_dev_put(dev);
955 module_put(THIS_MODULE);
956 return -EINVAL;
957 }
958 if ((err =
959 snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, 1))) {
960 module_put(ci->owner);
961 kfree(cii);
962 soundbus_dev_put(dev);
963 module_put(THIS_MODULE);
964 return err;
965 }
966 snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
967 &i2sbus_record_ops);
968 i2sdev->in.created = 1;
969 }
970
971 /* so we have to register the pcm after adding any substream
972 * to it because alsa doesn't create the devices for the
973 * substreams when we add them later.
974 * Therefore, force in and out on both busses (above) and
975 * register the pcm now instead of just after creating it.
976 */
977 err = snd_device_register(card, dev->pcm);
978 if (err) {
979 printk(KERN_ERR "i2sbus: error registering new pcm\n");
980 module_put(ci->owner);
981 kfree(cii);
982 soundbus_dev_put(dev);
983 module_put(THIS_MODULE);
984 return err;
985 }
986 /* no errors any more, so let's add this to our list */
987 list_add(&cii->list, &dev->codec_list);
988
989 dev->pcm->private_data = i2sdev;
990 dev->pcm->private_free = i2sbus_private_free;
991
992 /* well, we really should support scatter/gather DMA */
993 snd_pcm_lib_preallocate_pages_for_all(
994 dev->pcm, SNDRV_DMA_TYPE_DEV,
995 snd_dma_pci_data(macio_get_pci_dev(i2sdev->macio)),
996 64 * 1024, 64 * 1024);
997
998 return 0;
999}
1000
1001void i2sbus_detach_codec(struct soundbus_dev *dev, void *data)
1002{
1003 struct codec_info_item *cii = NULL, *i;
1004
1005 list_for_each_entry(i, &dev->codec_list, list) {
1006 if (i->codec_data == data) {
1007 cii = i;
1008 break;
1009 }
1010 }
1011 if (cii) {
1012 list_del(&cii->list);
1013 module_put(cii->codec->owner);
1014 kfree(cii);
1015 }
1016 /* no more codecs, but still a pcm? */
1017 if (list_empty(&dev->codec_list) && dev->pcm) {
1018 /* the actual cleanup is done by the callback above! */
1019 snd_device_free(dev->pcm->card, dev->pcm);
1020 }
1021}
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus.h b/sound/aoa/soundbus/i2sbus/i2sbus.h
new file mode 100644
index 000000000000..cfa5162e3b0f
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus.h
@@ -0,0 +1,112 @@
1/*
2 * i2sbus driver -- private definitions
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#ifndef __I2SBUS_H
9#define __I2SBUS_H
10#include <asm/dbdma.h>
11#include <linux/interrupt.h>
12#include <sound/pcm.h>
13#include <linux/spinlock.h>
14#include <linux/mutex.h>
15#include <asm/prom.h>
16#include "i2sbus-interface.h"
17#include "i2sbus-control.h"
18#include "../soundbus.h"
19
20struct i2sbus_control {
21 volatile struct i2s_control_regs __iomem *controlregs;
22 struct resource rsrc;
23 struct list_head list;
24};
25
26#define MAX_DBDMA_COMMANDS 32
27
28struct dbdma_command_mem {
29 dma_addr_t bus_addr;
30 dma_addr_t bus_cmd_start;
31 struct dbdma_cmd *cmds;
32 void *space;
33 int size;
34 u32 running:1;
35};
36
37struct pcm_info {
38 u32 created:1, /* has this direction been created with alsa? */
39 active:1; /* is this stream active? */
40 /* runtime information */
41 struct snd_pcm_substream *substream;
42 int current_period;
43 u32 frame_count;
44 struct dbdma_command_mem dbdma_ring;
45 volatile struct dbdma_regs __iomem *dbdma;
46};
47
48struct i2sbus_dev {
49 struct soundbus_dev sound;
50 struct macio_dev *macio;
51 struct i2sbus_control *control;
52 volatile struct i2s_interface_regs __iomem *intfregs;
53
54 struct resource resources[3];
55 struct resource *allocated_resource[3];
56 int interrupts[3];
57 char rnames[3][32];
58
59 /* info about currently active substreams */
60 struct pcm_info out, in;
61 snd_pcm_format_t format;
62 unsigned int rate;
63
64 /* list for a single controller */
65 struct list_head item;
66 /* number of bus on controller */
67 int bus_number;
68 /* for use by control layer */
69 struct pmf_function *enable,
70 *cell_enable,
71 *cell_disable,
72 *clock_enable,
73 *clock_disable;
74
75 /* locks */
76 /* spinlock for low-level interrupt locking */
77 spinlock_t low_lock;
78 /* mutex for high-level consistency */
79 struct mutex lock;
80};
81
82#define soundbus_dev_to_i2sbus_dev(sdev) \
83 container_of(sdev, struct i2sbus_dev, sound)
84
85/* pcm specific functions */
86extern int
87i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
88 struct codec_info *ci, void *data);
89extern void
90i2sbus_detach_codec(struct soundbus_dev *dev, void *data);
91extern irqreturn_t
92i2sbus_tx_intr(int irq, void *devid, struct pt_regs *regs);
93extern irqreturn_t
94i2sbus_rx_intr(int irq, void *devid, struct pt_regs *regs);
95
96/* control specific functions */
97extern int i2sbus_control_init(struct macio_dev* dev,
98 struct i2sbus_control **c);
99extern void i2sbus_control_destroy(struct i2sbus_control *c);
100extern int i2sbus_control_add_dev(struct i2sbus_control *c,
101 struct i2sbus_dev *i2sdev);
102extern void i2sbus_control_remove_dev(struct i2sbus_control *c,
103 struct i2sbus_dev *i2sdev);
104extern int i2sbus_control_enable(struct i2sbus_control *c,
105 struct i2sbus_dev *i2sdev);
106extern int i2sbus_control_cell(struct i2sbus_control *c,
107 struct i2sbus_dev *i2sdev,
108 int enable);
109extern int i2sbus_control_clock(struct i2sbus_control *c,
110 struct i2sbus_dev *i2sdev,
111 int enable);
112#endif /* __I2SBUS_H */
diff --git a/sound/aoa/soundbus/soundbus.h b/sound/aoa/soundbus/soundbus.h
new file mode 100644
index 000000000000..5c27297835d7
--- /dev/null
+++ b/sound/aoa/soundbus/soundbus.h
@@ -0,0 +1,202 @@
1/*
2 * soundbus generic definitions
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#ifndef __SOUNDBUS_H
9#define __SOUNDBUS_H
10
11#include <asm/of_device.h>
12#include <sound/pcm.h>
13#include <linux/list.h>
14
15
16/* When switching from master to slave or the other way around,
17 * you don't want to have the codec chip acting as clock source
18 * while the bus still is.
19 * More importantly, while switch from slave to master, you need
20 * to turn off the chip's master function first, but then there's
21 * no clock for a while and other chips might reset, so we notify
22 * their drivers after having switched.
23 * The constants here are codec-point of view, so when we switch
24 * the soundbus to master we tell the codec we're going to switch
25 * and give it CLOCK_SWITCH_PREPARE_SLAVE!
26 */
27enum clock_switch {
28 CLOCK_SWITCH_PREPARE_SLAVE,
29 CLOCK_SWITCH_PREPARE_MASTER,
30 CLOCK_SWITCH_SLAVE,
31 CLOCK_SWITCH_MASTER,
32 CLOCK_SWITCH_NOTIFY,
33};
34
35/* information on a transfer the codec can take */
36struct transfer_info {
37 u64 formats; /* SNDRV_PCM_FMTBIT_* */
38 unsigned int rates; /* SNDRV_PCM_RATE_* */
39 /* flags */
40 u32 transfer_in:1, /* input = 1, output = 0 */
41 must_be_clock_source:1;
42 /* for codecs to distinguish among their TIs */
43 int tag;
44};
45
46struct codec_info_item {
47 struct codec_info *codec;
48 void *codec_data;
49 struct soundbus_dev *sdev;
50 /* internal, to be used by the soundbus provider */
51 struct list_head list;
52};
53
54/* for prepare, where the codecs need to know
55 * what we're going to drive the bus with */
56struct bus_info {
57 /* see below */
58 int sysclock_factor;
59 int bus_factor;
60};
61
62/* information on the codec itself, plus function pointers */
63struct codec_info {
64 /* the module this lives in */
65 struct module *owner;
66
67 /* supported transfer possibilities, array terminated by
68 * formats or rates being 0. */
69 struct transfer_info *transfers;
70
71 /* Master clock speed factor
72 * to be used (master clock speed = sysclock_factor * sampling freq)
73 * Unused if the soundbus provider has no such notion.
74 */
75 int sysclock_factor;
76
77 /* Bus factor, bus clock speed = bus_factor * sampling freq)
78 * Unused if the soundbus provider has no such notion.
79 */
80 int bus_factor;
81
82 /* operations */
83 /* clock switching, see above */
84 int (*switch_clock)(struct codec_info_item *cii,
85 enum clock_switch clock);
86
87 /* called for each transfer_info when the user
88 * opens the pcm device to determine what the
89 * hardware can support at this point in time.
90 * That can depend on other user-switchable controls.
91 * Return 1 if usable, 0 if not.
92 * out points to another instance of a transfer_info
93 * which is initialised to the values in *ti, and
94 * it's format and rate values can be modified by
95 * the callback if it is necessary to further restrict
96 * the formats that can be used at the moment, for
97 * example when one codec has multiple logical codec
98 * info structs for multiple inputs.
99 */
100 int (*usable)(struct codec_info_item *cii,
101 struct transfer_info *ti,
102 struct transfer_info *out);
103
104 /* called when pcm stream is opened, probably not implemented
105 * most of the time since it isn't too useful */
106 int (*open)(struct codec_info_item *cii,
107 struct snd_pcm_substream *substream);
108
109 /* called when the pcm stream is closed, at this point
110 * the user choices can all be unlocked (see below) */
111 int (*close)(struct codec_info_item *cii,
112 struct snd_pcm_substream *substream);
113
114 /* if the codec must forbid some user choices because
115 * they are not valid with the substream/transfer info,
116 * it must do so here. Example: no digital output for
117 * incompatible framerate, say 8KHz, on Onyx.
118 * If the selected stuff in the substream is NOT
119 * compatible, you have to reject this call! */
120 int (*prepare)(struct codec_info_item *cii,
121 struct bus_info *bi,
122 struct snd_pcm_substream *substream);
123
124 /* start() is called before data is pushed to the codec.
125 * Note that start() must be atomic! */
126 int (*start)(struct codec_info_item *cii,
127 struct snd_pcm_substream *substream);
128
129 /* stop() is called after data is no longer pushed to the codec.
130 * Note that stop() must be atomic! */
131 int (*stop)(struct codec_info_item *cii,
132 struct snd_pcm_substream *substream);
133
134 int (*suspend)(struct codec_info_item *cii, pm_message_t state);
135 int (*resume)(struct codec_info_item *cii);
136};
137
138/* information on a soundbus device */
139struct soundbus_dev {
140 /* the bus it belongs to */
141 struct list_head onbuslist;
142
143 /* the of device it represents */
144 struct of_device ofdev;
145
146 /* what modules go by */
147 char modalias[32];
148
149 /* These fields must be before attach_codec can be called.
150 * They should be set by the owner of the alsa card object
151 * that is needed, and whoever sets them must make sure
152 * that they are unique within that alsa card object. */
153 char *pcmname;
154 int pcmid;
155
156 /* this is assigned by the soundbus provider in attach_codec */
157 struct snd_pcm *pcm;
158
159 /* operations */
160 /* attach a codec to this soundbus, give the alsa
161 * card object the PCMs for this soundbus should be in.
162 * The 'data' pointer must be unique, it is used as the
163 * key for detach_codec(). */
164 int (*attach_codec)(struct soundbus_dev *dev, struct snd_card *card,
165 struct codec_info *ci, void *data);
166 void (*detach_codec)(struct soundbus_dev *dev, void *data);
167 /* TODO: suspend/resume */
168
169 /* private for the soundbus provider */
170 struct list_head codec_list;
171 u32 have_out:1, have_in:1;
172};
173#define to_soundbus_device(d) container_of(d, struct soundbus_dev, ofdev.dev)
174#define of_to_soundbus_device(d) container_of(d, struct soundbus_dev, ofdev)
175
176extern int soundbus_add_one(struct soundbus_dev *dev);
177extern void soundbus_remove_one(struct soundbus_dev *dev);
178
179extern struct soundbus_dev *soundbus_dev_get(struct soundbus_dev *dev);
180extern void soundbus_dev_put(struct soundbus_dev *dev);
181
182struct soundbus_driver {
183 char *name;
184 struct module *owner;
185
186 /* we don't implement any matching at all */
187
188 int (*probe)(struct soundbus_dev* dev);
189 int (*remove)(struct soundbus_dev* dev);
190
191 int (*suspend)(struct soundbus_dev* dev, pm_message_t state);
192 int (*resume)(struct soundbus_dev* dev);
193 int (*shutdown)(struct soundbus_dev* dev);
194
195 struct device_driver driver;
196};
197#define to_soundbus_driver(drv) container_of(drv,struct soundbus_driver, driver)
198
199extern int soundbus_register_driver(struct soundbus_driver *drv);
200extern void soundbus_unregister_driver(struct soundbus_driver *drv);
201
202#endif /* __SOUNDBUS_H */
diff --git a/sound/aoa/soundbus/sysfs.c b/sound/aoa/soundbus/sysfs.c
new file mode 100644
index 000000000000..d31f8146952a
--- /dev/null
+++ b/sound/aoa/soundbus/sysfs.c
@@ -0,0 +1,43 @@
1#include <linux/config.h>
2#include <linux/kernel.h>
3#include <linux/stat.h>
4/* FIX UP */
5#include "soundbus.h"
6
7#define soundbus_config_of_attr(field, format_string) \
8static ssize_t \
9field##_show (struct device *dev, struct device_attribute *attr, \
10 char *buf) \
11{ \
12 struct soundbus_dev *mdev = to_soundbus_device (dev); \
13 return sprintf (buf, format_string, mdev->ofdev.node->field); \
14}
15
16static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
17 char *buf)
18{
19 struct soundbus_dev *sdev = to_soundbus_device(dev);
20 struct of_device *of = &sdev->ofdev;
21 int length;
22
23 if (*sdev->modalias) {
24 strlcpy(buf, sdev->modalias, sizeof(sdev->modalias) + 1);
25 strcat(buf, "\n");
26 length = strlen(buf);
27 } else {
28 length = sprintf(buf, "of:N%sT%s\n",
29 of->node->name, of->node->type);
30 }
31
32 return length;
33}
34
35soundbus_config_of_attr (name, "%s\n");
36soundbus_config_of_attr (type, "%s\n");
37
38struct device_attribute soundbus_dev_attrs[] = {
39 __ATTR_RO(name),
40 __ATTR_RO(type),
41 __ATTR_RO(modalias),
42 __ATTR_NULL
43};
diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c
index 13057d92f08a..b88fb0c5a68a 100644
--- a/sound/arm/sa11xx-uda1341.c
+++ b/sound/arm/sa11xx-uda1341.c
@@ -112,7 +112,7 @@ MODULE_LICENSE("GPL");
112MODULE_DESCRIPTION("SA1100/SA1111 + UDA1341TS driver for ALSA"); 112MODULE_DESCRIPTION("SA1100/SA1111 + UDA1341TS driver for ALSA");
113MODULE_SUPPORTED_DEVICE("{{UDA1341,iPAQ H3600 UDA1341TS}}"); 113MODULE_SUPPORTED_DEVICE("{{UDA1341,iPAQ H3600 UDA1341TS}}");
114 114
115static char *id = NULL; /* ID for this card */ 115static char *id; /* ID for this card */
116 116
117module_param(id, charp, 0444); 117module_param(id, charp, 0444);
118MODULE_PARM_DESC(id, "ID string for SA1100/SA1111 + UDA1341TS soundcard."); 118MODULE_PARM_DESC(id, "ID string for SA1100/SA1111 + UDA1341TS soundcard.");
@@ -984,11 +984,15 @@ static int __init sa11xx_uda1341_init(void)
984 if ((err = platform_driver_register(&sa11xx_uda1341_driver)) < 0) 984 if ((err = platform_driver_register(&sa11xx_uda1341_driver)) < 0)
985 return err; 985 return err;
986 device = platform_device_register_simple(SA11XX_UDA1341_DRIVER, -1, NULL, 0); 986 device = platform_device_register_simple(SA11XX_UDA1341_DRIVER, -1, NULL, 0);
987 if (IS_ERR(device)) { 987 if (!IS_ERR(device)) {
988 platform_driver_unregister(&sa11xx_uda1341_driver); 988 if (platform_get_drvdata(device))
989 return PTR_ERR(device); 989 return 0;
990 } 990 platform_device_unregister(device);
991 return 0; 991 err = -ENODEV
992 } else
993 err = PTR_ERR(device);
994 platform_driver_unregister(&sa11xx_uda1341_driver);
995 return err;
992} 996}
993 997
994static void __exit sa11xx_uda1341_exit(void) 998static void __exit sa11xx_uda1341_exit(void)
diff --git a/sound/core/control.c b/sound/core/control.c
index 22565c9b9603..bb397eaa7187 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -176,6 +176,8 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
176 read_unlock(&card->ctl_files_rwlock); 176 read_unlock(&card->ctl_files_rwlock);
177} 177}
178 178
179EXPORT_SYMBOL(snd_ctl_notify);
180
179/** 181/**
180 * snd_ctl_new - create a control instance from the template 182 * snd_ctl_new - create a control instance from the template
181 * @control: the control template 183 * @control: the control template
@@ -204,6 +206,8 @@ struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, unsigned int acce
204 return kctl; 206 return kctl;
205} 207}
206 208
209EXPORT_SYMBOL(snd_ctl_new);
210
207/** 211/**
208 * snd_ctl_new1 - create a control instance from the template 212 * snd_ctl_new1 - create a control instance from the template
209 * @ncontrol: the initialization record 213 * @ncontrol: the initialization record
@@ -242,6 +246,8 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
242 return snd_ctl_new(&kctl, access); 246 return snd_ctl_new(&kctl, access);
243} 247}
244 248
249EXPORT_SYMBOL(snd_ctl_new1);
250
245/** 251/**
246 * snd_ctl_free_one - release the control instance 252 * snd_ctl_free_one - release the control instance
247 * @kcontrol: the control instance 253 * @kcontrol: the control instance
@@ -259,6 +265,8 @@ void snd_ctl_free_one(struct snd_kcontrol *kcontrol)
259 } 265 }
260} 266}
261 267
268EXPORT_SYMBOL(snd_ctl_free_one);
269
262static unsigned int snd_ctl_hole_check(struct snd_card *card, 270static unsigned int snd_ctl_hole_check(struct snd_card *card,
263 unsigned int count) 271 unsigned int count)
264{ 272{
@@ -347,6 +355,8 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
347 return err; 355 return err;
348} 356}
349 357
358EXPORT_SYMBOL(snd_ctl_add);
359
350/** 360/**
351 * snd_ctl_remove - remove the control from the card and release it 361 * snd_ctl_remove - remove the control from the card and release it
352 * @card: the card instance 362 * @card: the card instance
@@ -373,6 +383,8 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
373 return 0; 383 return 0;
374} 384}
375 385
386EXPORT_SYMBOL(snd_ctl_remove);
387
376/** 388/**
377 * snd_ctl_remove_id - remove the control of the given id and release it 389 * snd_ctl_remove_id - remove the control of the given id and release it
378 * @card: the card instance 390 * @card: the card instance
@@ -399,6 +411,8 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id)
399 return ret; 411 return ret;
400} 412}
401 413
414EXPORT_SYMBOL(snd_ctl_remove_id);
415
402/** 416/**
403 * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it 417 * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it
404 * @file: active control handle 418 * @file: active control handle
@@ -461,6 +475,8 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
461 return 0; 475 return 0;
462} 476}
463 477
478EXPORT_SYMBOL(snd_ctl_rename_id);
479
464/** 480/**
465 * snd_ctl_find_numid - find the control instance with the given number-id 481 * snd_ctl_find_numid - find the control instance with the given number-id
466 * @card: the card instance 482 * @card: the card instance
@@ -487,6 +503,8 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi
487 return NULL; 503 return NULL;
488} 504}
489 505
506EXPORT_SYMBOL(snd_ctl_find_numid);
507
490/** 508/**
491 * snd_ctl_find_id - find the control instance with the given id 509 * snd_ctl_find_id - find the control instance with the given id
492 * @card: the card instance 510 * @card: the card instance
@@ -527,6 +545,8 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
527 return NULL; 545 return NULL;
528} 546}
529 547
548EXPORT_SYMBOL(snd_ctl_find_id);
549
530static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, 550static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
531 unsigned int cmd, void __user *arg) 551 unsigned int cmd, void __user *arg)
532{ 552{
@@ -704,6 +724,8 @@ int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control)
704 return result; 724 return result;
705} 725}
706 726
727EXPORT_SYMBOL(snd_ctl_elem_read);
728
707static int snd_ctl_elem_read_user(struct snd_card *card, 729static int snd_ctl_elem_read_user(struct snd_card *card,
708 struct snd_ctl_elem_value __user *_control) 730 struct snd_ctl_elem_value __user *_control)
709{ 731{
@@ -767,6 +789,8 @@ int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
767 return result; 789 return result;
768} 790}
769 791
792EXPORT_SYMBOL(snd_ctl_elem_write);
793
770static int snd_ctl_elem_write_user(struct snd_ctl_file *file, 794static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
771 struct snd_ctl_elem_value __user *_control) 795 struct snd_ctl_elem_value __user *_control)
772{ 796{
@@ -1199,11 +1223,15 @@ int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn)
1199 return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls); 1223 return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls);
1200} 1224}
1201 1225
1226EXPORT_SYMBOL(snd_ctl_register_ioctl);
1227
1202#ifdef CONFIG_COMPAT 1228#ifdef CONFIG_COMPAT
1203int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn) 1229int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn)
1204{ 1230{
1205 return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls); 1231 return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls);
1206} 1232}
1233
1234EXPORT_SYMBOL(snd_ctl_register_ioctl_compat);
1207#endif 1235#endif
1208 1236
1209/* 1237/*
@@ -1236,12 +1264,15 @@ int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn)
1236 return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls); 1264 return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls);
1237} 1265}
1238 1266
1267EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
1268
1239#ifdef CONFIG_COMPAT 1269#ifdef CONFIG_COMPAT
1240int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn) 1270int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn)
1241{ 1271{
1242 return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls); 1272 return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls);
1243} 1273}
1244 1274
1275EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
1245#endif 1276#endif
1246 1277
1247static int snd_ctl_fasync(int fd, struct file * file, int on) 1278static int snd_ctl_fasync(int fd, struct file * file, int on)
diff --git a/sound/core/device.c b/sound/core/device.c
index b1cf6ec56784..6ce4da4a1081 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -63,6 +63,8 @@ int snd_device_new(struct snd_card *card, snd_device_type_t type,
63 return 0; 63 return 0;
64} 64}
65 65
66EXPORT_SYMBOL(snd_device_new);
67
66/** 68/**
67 * snd_device_free - release the device from the card 69 * snd_device_free - release the device from the card
68 * @card: the card instance 70 * @card: the card instance
@@ -107,6 +109,8 @@ int snd_device_free(struct snd_card *card, void *device_data)
107 return -ENXIO; 109 return -ENXIO;
108} 110}
109 111
112EXPORT_SYMBOL(snd_device_free);
113
110/** 114/**
111 * snd_device_disconnect - disconnect the device 115 * snd_device_disconnect - disconnect the device
112 * @card: the card instance 116 * @card: the card instance
@@ -182,6 +186,8 @@ int snd_device_register(struct snd_card *card, void *device_data)
182 return -ENXIO; 186 return -ENXIO;
183} 187}
184 188
189EXPORT_SYMBOL(snd_device_register);
190
185/* 191/*
186 * register all the devices on the card. 192 * register all the devices on the card.
187 * called from init.c 193 * called from init.c
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 2524e66eccdd..8bd0dcc93eba 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -486,7 +486,6 @@ static void __init snd_hwdep_proc_init(void)
486 struct snd_info_entry *entry; 486 struct snd_info_entry *entry;
487 487
488 if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) { 488 if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) {
489 entry->c.text.read_size = PAGE_SIZE;
490 entry->c.text.read = snd_hwdep_proc_read; 489 entry->c.text.read = snd_hwdep_proc_read;
491 if (snd_info_register(entry) < 0) { 490 if (snd_info_register(entry) < 0) {
492 snd_info_free_entry(entry); 491 snd_info_free_entry(entry);
diff --git a/sound/core/info.c b/sound/core/info.c
index 2582b74d3199..10c1772bf3ea 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -21,7 +21,6 @@
21 21
22#include <sound/driver.h> 22#include <sound/driver.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/vmalloc.h>
25#include <linux/time.h> 24#include <linux/time.h>
26#include <linux/smp_lock.h> 25#include <linux/smp_lock.h>
27#include <linux/string.h> 26#include <linux/string.h>
@@ -82,6 +81,24 @@ static int snd_info_version_init(void);
82static int snd_info_version_done(void); 81static int snd_info_version_done(void);
83 82
84 83
84/* resize the proc r/w buffer */
85static int resize_info_buffer(struct snd_info_buffer *buffer,
86 unsigned int nsize)
87{
88 char *nbuf;
89
90 nsize = PAGE_ALIGN(nsize);
91 nbuf = kmalloc(nsize, GFP_KERNEL);
92 if (! nbuf)
93 return -ENOMEM;
94
95 memcpy(nbuf, buffer->buffer, buffer->len);
96 kfree(buffer->buffer);
97 buffer->buffer = nbuf;
98 buffer->len = nsize;
99 return 0;
100}
101
85/** 102/**
86 * snd_iprintf - printf on the procfs buffer 103 * snd_iprintf - printf on the procfs buffer
87 * @buffer: the procfs buffer 104 * @buffer: the procfs buffer
@@ -95,30 +112,43 @@ int snd_iprintf(struct snd_info_buffer *buffer, char *fmt,...)
95{ 112{
96 va_list args; 113 va_list args;
97 int len, res; 114 int len, res;
115 int err = 0;
98 116
117 might_sleep();
99 if (buffer->stop || buffer->error) 118 if (buffer->stop || buffer->error)
100 return 0; 119 return 0;
101 len = buffer->len - buffer->size; 120 len = buffer->len - buffer->size;
102 va_start(args, fmt); 121 va_start(args, fmt);
103 res = vsnprintf(buffer->curr, len, fmt, args); 122 for (;;) {
104 va_end(args); 123 res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, args);
105 if (res >= len) { 124 if (res < len)
106 buffer->stop = 1; 125 break;
107 return 0; 126 err = resize_info_buffer(buffer, buffer->len + PAGE_SIZE);
127 if (err < 0)
128 break;
129 len = buffer->len - buffer->size;
108 } 130 }
131 va_end(args);
132
133 if (err < 0)
134 return err;
109 buffer->curr += res; 135 buffer->curr += res;
110 buffer->size += res; 136 buffer->size += res;
111 return res; 137 return res;
112} 138}
113 139
140EXPORT_SYMBOL(snd_iprintf);
141
114/* 142/*
115 143
116 */ 144 */
117 145
118static struct proc_dir_entry *snd_proc_root = NULL; 146static struct proc_dir_entry *snd_proc_root;
119struct snd_info_entry *snd_seq_root = NULL; 147struct snd_info_entry *snd_seq_root;
148EXPORT_SYMBOL(snd_seq_root);
149
120#ifdef CONFIG_SND_OSSEMUL 150#ifdef CONFIG_SND_OSSEMUL
121struct snd_info_entry *snd_oss_root = NULL; 151struct snd_info_entry *snd_oss_root;
122#endif 152#endif
123 153
124static inline void snd_info_entry_prepare(struct proc_dir_entry *de) 154static inline void snd_info_entry_prepare(struct proc_dir_entry *de)
@@ -221,7 +251,7 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
221 struct snd_info_private_data *data; 251 struct snd_info_private_data *data;
222 struct snd_info_entry *entry; 252 struct snd_info_entry *entry;
223 struct snd_info_buffer *buf; 253 struct snd_info_buffer *buf;
224 size_t size = 0; 254 ssize_t size = 0;
225 loff_t pos; 255 loff_t pos;
226 256
227 data = file->private_data; 257 data = file->private_data;
@@ -237,14 +267,20 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
237 buf = data->wbuffer; 267 buf = data->wbuffer;
238 if (buf == NULL) 268 if (buf == NULL)
239 return -EIO; 269 return -EIO;
240 if (pos >= buf->len) 270 mutex_lock(&entry->access);
241 return -ENOMEM; 271 if (pos + count >= buf->len) {
242 size = buf->len - pos; 272 if (resize_info_buffer(buf, pos + count)) {
243 size = min(count, size); 273 mutex_unlock(&entry->access);
244 if (copy_from_user(buf->buffer + pos, buffer, size)) 274 return -ENOMEM;
275 }
276 }
277 if (copy_from_user(buf->buffer + pos, buffer, count)) {
278 mutex_unlock(&entry->access);
245 return -EFAULT; 279 return -EFAULT;
246 if ((long)buf->size < pos + size) 280 }
247 buf->size = pos + size; 281 buf->size = pos + count;
282 mutex_unlock(&entry->access);
283 size = count;
248 break; 284 break;
249 case SNDRV_INFO_CONTENT_DATA: 285 case SNDRV_INFO_CONTENT_DATA:
250 if (entry->c.ops->write) 286 if (entry->c.ops->write)
@@ -279,18 +315,14 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
279 } 315 }
280 mode = file->f_flags & O_ACCMODE; 316 mode = file->f_flags & O_ACCMODE;
281 if (mode == O_RDONLY || mode == O_RDWR) { 317 if (mode == O_RDONLY || mode == O_RDWR) {
282 if ((entry->content == SNDRV_INFO_CONTENT_TEXT && 318 if ((entry->content == SNDRV_INFO_CONTENT_DATA &&
283 !entry->c.text.read_size) ||
284 (entry->content == SNDRV_INFO_CONTENT_DATA &&
285 entry->c.ops->read == NULL)) { 319 entry->c.ops->read == NULL)) {
286 err = -ENODEV; 320 err = -ENODEV;
287 goto __error; 321 goto __error;
288 } 322 }
289 } 323 }
290 if (mode == O_WRONLY || mode == O_RDWR) { 324 if (mode == O_WRONLY || mode == O_RDWR) {
291 if ((entry->content == SNDRV_INFO_CONTENT_TEXT && 325 if ((entry->content == SNDRV_INFO_CONTENT_DATA &&
292 !entry->c.text.write_size) ||
293 (entry->content == SNDRV_INFO_CONTENT_DATA &&
294 entry->c.ops->write == NULL)) { 326 entry->c.ops->write == NULL)) {
295 err = -ENODEV; 327 err = -ENODEV;
296 goto __error; 328 goto __error;
@@ -306,49 +338,23 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
306 case SNDRV_INFO_CONTENT_TEXT: 338 case SNDRV_INFO_CONTENT_TEXT:
307 if (mode == O_RDONLY || mode == O_RDWR) { 339 if (mode == O_RDONLY || mode == O_RDWR) {
308 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); 340 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
309 if (buffer == NULL) { 341 if (buffer == NULL)
310 kfree(data); 342 goto __nomem;
311 err = -ENOMEM;
312 goto __error;
313 }
314 buffer->len = (entry->c.text.read_size +
315 (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
316 buffer->buffer = vmalloc(buffer->len);
317 if (buffer->buffer == NULL) {
318 kfree(buffer);
319 kfree(data);
320 err = -ENOMEM;
321 goto __error;
322 }
323 buffer->curr = buffer->buffer;
324 data->rbuffer = buffer; 343 data->rbuffer = buffer;
344 buffer->len = PAGE_SIZE;
345 buffer->buffer = kmalloc(buffer->len, GFP_KERNEL);
346 if (buffer->buffer == NULL)
347 goto __nomem;
325 } 348 }
326 if (mode == O_WRONLY || mode == O_RDWR) { 349 if (mode == O_WRONLY || mode == O_RDWR) {
327 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); 350 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
328 if (buffer == NULL) { 351 if (buffer == NULL)
329 if (mode == O_RDWR) { 352 goto __nomem;
330 vfree(data->rbuffer->buffer);
331 kfree(data->rbuffer);
332 }
333 kfree(data);
334 err = -ENOMEM;
335 goto __error;
336 }
337 buffer->len = (entry->c.text.write_size +
338 (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
339 buffer->buffer = vmalloc(buffer->len);
340 if (buffer->buffer == NULL) {
341 if (mode == O_RDWR) {
342 vfree(data->rbuffer->buffer);
343 kfree(data->rbuffer);
344 }
345 kfree(buffer);
346 kfree(data);
347 err = -ENOMEM;
348 goto __error;
349 }
350 buffer->curr = buffer->buffer;
351 data->wbuffer = buffer; 353 data->wbuffer = buffer;
354 buffer->len = PAGE_SIZE;
355 buffer->buffer = kmalloc(buffer->len, GFP_KERNEL);
356 if (buffer->buffer == NULL)
357 goto __nomem;
352 } 358 }
353 break; 359 break;
354 case SNDRV_INFO_CONTENT_DATA: /* data */ 360 case SNDRV_INFO_CONTENT_DATA: /* data */
@@ -373,6 +379,17 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
373 } 379 }
374 return 0; 380 return 0;
375 381
382 __nomem:
383 if (data->rbuffer) {
384 kfree(data->rbuffer->buffer);
385 kfree(data->rbuffer);
386 }
387 if (data->wbuffer) {
388 kfree(data->wbuffer->buffer);
389 kfree(data->wbuffer);
390 }
391 kfree(data);
392 err = -ENOMEM;
376 __error: 393 __error:
377 module_put(entry->module); 394 module_put(entry->module);
378 __error1: 395 __error1:
@@ -391,11 +408,11 @@ static int snd_info_entry_release(struct inode *inode, struct file *file)
391 entry = data->entry; 408 entry = data->entry;
392 switch (entry->content) { 409 switch (entry->content) {
393 case SNDRV_INFO_CONTENT_TEXT: 410 case SNDRV_INFO_CONTENT_TEXT:
394 if (mode == O_RDONLY || mode == O_RDWR) { 411 if (data->rbuffer) {
395 vfree(data->rbuffer->buffer); 412 kfree(data->rbuffer->buffer);
396 kfree(data->rbuffer); 413 kfree(data->rbuffer);
397 } 414 }
398 if (mode == O_WRONLY || mode == O_RDWR) { 415 if (data->wbuffer) {
399 if (entry->c.text.write) { 416 if (entry->c.text.write) {
400 entry->c.text.write(entry, data->wbuffer); 417 entry->c.text.write(entry, data->wbuffer);
401 if (data->wbuffer->error) { 418 if (data->wbuffer->error) {
@@ -404,7 +421,7 @@ static int snd_info_entry_release(struct inode *inode, struct file *file)
404 data->wbuffer->error); 421 data->wbuffer->error);
405 } 422 }
406 } 423 }
407 vfree(data->wbuffer->buffer); 424 kfree(data->wbuffer->buffer);
408 kfree(data->wbuffer); 425 kfree(data->wbuffer);
409 } 426 }
410 break; 427 break;
@@ -664,29 +681,29 @@ int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len)
664 if (len <= 0 || buffer->stop || buffer->error) 681 if (len <= 0 || buffer->stop || buffer->error)
665 return 1; 682 return 1;
666 while (--len > 0) { 683 while (--len > 0) {
667 c = *buffer->curr++; 684 c = buffer->buffer[buffer->curr++];
668 if (c == '\n') { 685 if (c == '\n') {
669 if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { 686 if (buffer->curr >= buffer->size)
670 buffer->stop = 1; 687 buffer->stop = 1;
671 }
672 break; 688 break;
673 } 689 }
674 *line++ = c; 690 *line++ = c;
675 if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { 691 if (buffer->curr >= buffer->size) {
676 buffer->stop = 1; 692 buffer->stop = 1;
677 break; 693 break;
678 } 694 }
679 } 695 }
680 while (c != '\n' && !buffer->stop) { 696 while (c != '\n' && !buffer->stop) {
681 c = *buffer->curr++; 697 c = buffer->buffer[buffer->curr++];
682 if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { 698 if (buffer->curr >= buffer->size)
683 buffer->stop = 1; 699 buffer->stop = 1;
684 }
685 } 700 }
686 *line = '\0'; 701 *line = '\0';
687 return 0; 702 return 0;
688} 703}
689 704
705EXPORT_SYMBOL(snd_info_get_line);
706
690/** 707/**
691 * snd_info_get_str - parse a string token 708 * snd_info_get_str - parse a string token
692 * @dest: the buffer to store the string token 709 * @dest: the buffer to store the string token
@@ -723,6 +740,8 @@ char *snd_info_get_str(char *dest, char *src, int len)
723 return src; 740 return src;
724} 741}
725 742
743EXPORT_SYMBOL(snd_info_get_str);
744
726/** 745/**
727 * snd_info_create_entry - create an info entry 746 * snd_info_create_entry - create an info entry
728 * @name: the proc file name 747 * @name: the proc file name
@@ -774,6 +793,8 @@ struct snd_info_entry *snd_info_create_module_entry(struct module * module,
774 return entry; 793 return entry;
775} 794}
776 795
796EXPORT_SYMBOL(snd_info_create_module_entry);
797
777/** 798/**
778 * snd_info_create_card_entry - create an info entry for the given card 799 * snd_info_create_card_entry - create an info entry for the given card
779 * @card: the card instance 800 * @card: the card instance
@@ -797,6 +818,8 @@ struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card,
797 return entry; 818 return entry;
798} 819}
799 820
821EXPORT_SYMBOL(snd_info_create_card_entry);
822
800static int snd_info_dev_free_entry(struct snd_device *device) 823static int snd_info_dev_free_entry(struct snd_device *device)
801{ 824{
802 struct snd_info_entry *entry = device->device_data; 825 struct snd_info_entry *entry = device->device_data;
@@ -867,6 +890,8 @@ int snd_card_proc_new(struct snd_card *card, const char *name,
867 return 0; 890 return 0;
868} 891}
869 892
893EXPORT_SYMBOL(snd_card_proc_new);
894
870/** 895/**
871 * snd_info_free_entry - release the info entry 896 * snd_info_free_entry - release the info entry
872 * @entry: the info entry 897 * @entry: the info entry
@@ -883,6 +908,8 @@ void snd_info_free_entry(struct snd_info_entry * entry)
883 kfree(entry); 908 kfree(entry);
884} 909}
885 910
911EXPORT_SYMBOL(snd_info_free_entry);
912
886/** 913/**
887 * snd_info_register - register the info entry 914 * snd_info_register - register the info entry
888 * @entry: the info entry 915 * @entry: the info entry
@@ -913,6 +940,8 @@ int snd_info_register(struct snd_info_entry * entry)
913 return 0; 940 return 0;
914} 941}
915 942
943EXPORT_SYMBOL(snd_info_register);
944
916/** 945/**
917 * snd_info_unregister - de-register the info entry 946 * snd_info_unregister - de-register the info entry
918 * @entry: the info entry 947 * @entry: the info entry
@@ -937,11 +966,13 @@ int snd_info_unregister(struct snd_info_entry * entry)
937 return 0; 966 return 0;
938} 967}
939 968
969EXPORT_SYMBOL(snd_info_unregister);
970
940/* 971/*
941 972
942 */ 973 */
943 974
944static struct snd_info_entry *snd_info_version_entry = NULL; 975static struct snd_info_entry *snd_info_version_entry;
945 976
946static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 977static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
947{ 978{
@@ -958,7 +989,6 @@ static int __init snd_info_version_init(void)
958 entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL); 989 entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL);
959 if (entry == NULL) 990 if (entry == NULL)
960 return -ENOMEM; 991 return -ENOMEM;
961 entry->c.text.read_size = 256;
962 entry->c.text.read = snd_info_version_read; 992 entry->c.text.read = snd_info_version_read;
963 if (snd_info_register(entry) < 0) { 993 if (snd_info_register(entry) < 0) {
964 snd_info_free_entry(entry); 994 snd_info_free_entry(entry);
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index f9ce854b3d11..bb2c40d0ab66 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -64,6 +64,8 @@ int snd_oss_info_register(int dev, int num, char *string)
64 return 0; 64 return 0;
65} 65}
66 66
67EXPORT_SYMBOL(snd_oss_info_register);
68
67extern void snd_card_info_read_oss(struct snd_info_buffer *buffer); 69extern void snd_card_info_read_oss(struct snd_info_buffer *buffer);
68 70
69static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev) 71static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev)
@@ -117,7 +119,6 @@ int snd_info_minor_register(void)
117 119
118 memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings)); 120 memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings));
119 if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", snd_oss_root)) != NULL) { 121 if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", snd_oss_root)) != NULL) {
120 entry->c.text.read_size = 2048;
121 entry->c.text.read = snd_sndstat_proc_read; 122 entry->c.text.read = snd_sndstat_proc_read;
122 if (snd_info_register(entry) < 0) { 123 if (snd_info_register(entry) < 0) {
123 snd_info_free_entry(entry); 124 snd_info_free_entry(entry);
diff --git a/sound/core/init.c b/sound/core/init.c
index 39ed2e5bb0af..4d9258884e44 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -38,12 +38,15 @@ struct snd_shutdown_f_ops {
38 struct snd_shutdown_f_ops *next; 38 struct snd_shutdown_f_ops *next;
39}; 39};
40 40
41unsigned int snd_cards_lock = 0; /* locked for registering/using */ 41static unsigned int snd_cards_lock; /* locked for registering/using */
42struct snd_card *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL}; 42struct snd_card *snd_cards[SNDRV_CARDS];
43DEFINE_RWLOCK(snd_card_rwlock); 43EXPORT_SYMBOL(snd_cards);
44
45static DEFINE_MUTEX(snd_card_mutex);
44 46
45#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 47#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
46int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag); 48int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag);
49EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
47#endif 50#endif
48 51
49#ifdef CONFIG_PROC_FS 52#ifdef CONFIG_PROC_FS
@@ -66,7 +69,6 @@ static inline int init_info_for_card(struct snd_card *card)
66 snd_printd("unable to create card entry\n"); 69 snd_printd("unable to create card entry\n");
67 return err; 70 return err;
68 } 71 }
69 entry->c.text.read_size = PAGE_SIZE;
70 entry->c.text.read = snd_card_id_read; 72 entry->c.text.read = snd_card_id_read;
71 if (snd_info_register(entry) < 0) { 73 if (snd_info_register(entry) < 0) {
72 snd_info_free_entry(entry); 74 snd_info_free_entry(entry);
@@ -110,7 +112,7 @@ struct snd_card *snd_card_new(int idx, const char *xid,
110 strlcpy(card->id, xid, sizeof(card->id)); 112 strlcpy(card->id, xid, sizeof(card->id));
111 } 113 }
112 err = 0; 114 err = 0;
113 write_lock(&snd_card_rwlock); 115 mutex_lock(&snd_card_mutex);
114 if (idx < 0) { 116 if (idx < 0) {
115 int idx2; 117 int idx2;
116 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) 118 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
@@ -128,12 +130,12 @@ struct snd_card *snd_card_new(int idx, const char *xid,
128 else 130 else
129 err = -ENODEV; 131 err = -ENODEV;
130 if (idx < 0 || err < 0) { 132 if (idx < 0 || err < 0) {
131 write_unlock(&snd_card_rwlock); 133 mutex_unlock(&snd_card_mutex);
132 snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1); 134 snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1);
133 goto __error; 135 goto __error;
134 } 136 }
135 snd_cards_lock |= 1 << idx; /* lock it */ 137 snd_cards_lock |= 1 << idx; /* lock it */
136 write_unlock(&snd_card_rwlock); 138 mutex_unlock(&snd_card_mutex);
137 card->number = idx; 139 card->number = idx;
138 card->module = module; 140 card->module = module;
139 INIT_LIST_HEAD(&card->devices); 141 INIT_LIST_HEAD(&card->devices);
@@ -169,6 +171,19 @@ struct snd_card *snd_card_new(int idx, const char *xid,
169 return NULL; 171 return NULL;
170} 172}
171 173
174EXPORT_SYMBOL(snd_card_new);
175
176/* return non-zero if a card is already locked */
177int snd_card_locked(int card)
178{
179 int locked;
180
181 mutex_lock(&snd_card_mutex);
182 locked = snd_cards_lock & (1 << card);
183 mutex_unlock(&snd_card_mutex);
184 return locked;
185}
186
172static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig) 187static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig)
173{ 188{
174 return -ENODEV; 189 return -ENODEV;
@@ -236,9 +251,9 @@ int snd_card_disconnect(struct snd_card *card)
236 spin_unlock(&card->files_lock); 251 spin_unlock(&card->files_lock);
237 252
238 /* phase 1: disable fops (user space) operations for ALSA API */ 253 /* phase 1: disable fops (user space) operations for ALSA API */
239 write_lock(&snd_card_rwlock); 254 mutex_lock(&snd_card_mutex);
240 snd_cards[card->number] = NULL; 255 snd_cards[card->number] = NULL;
241 write_unlock(&snd_card_rwlock); 256 mutex_unlock(&snd_card_mutex);
242 257
243 /* phase 2: replace file->f_op with special dummy operations */ 258 /* phase 2: replace file->f_op with special dummy operations */
244 259
@@ -298,6 +313,8 @@ int snd_card_disconnect(struct snd_card *card)
298 return 0; 313 return 0;
299} 314}
300 315
316EXPORT_SYMBOL(snd_card_disconnect);
317
301/** 318/**
302 * snd_card_free - frees given soundcard structure 319 * snd_card_free - frees given soundcard structure
303 * @card: soundcard structure 320 * @card: soundcard structure
@@ -315,9 +332,9 @@ int snd_card_free(struct snd_card *card)
315 332
316 if (card == NULL) 333 if (card == NULL)
317 return -EINVAL; 334 return -EINVAL;
318 write_lock(&snd_card_rwlock); 335 mutex_lock(&snd_card_mutex);
319 snd_cards[card->number] = NULL; 336 snd_cards[card->number] = NULL;
320 write_unlock(&snd_card_rwlock); 337 mutex_unlock(&snd_card_mutex);
321 338
322#ifdef CONFIG_PM 339#ifdef CONFIG_PM
323 wake_up(&card->power_sleep); 340 wake_up(&card->power_sleep);
@@ -353,13 +370,15 @@ int snd_card_free(struct snd_card *card)
353 card->s_f_ops = s_f_ops->next; 370 card->s_f_ops = s_f_ops->next;
354 kfree(s_f_ops); 371 kfree(s_f_ops);
355 } 372 }
356 write_lock(&snd_card_rwlock); 373 mutex_lock(&snd_card_mutex);
357 snd_cards_lock &= ~(1 << card->number); 374 snd_cards_lock &= ~(1 << card->number);
358 write_unlock(&snd_card_rwlock); 375 mutex_unlock(&snd_card_mutex);
359 kfree(card); 376 kfree(card);
360 return 0; 377 return 0;
361} 378}
362 379
380EXPORT_SYMBOL(snd_card_free);
381
363static void snd_card_free_thread(void * __card) 382static void snd_card_free_thread(void * __card)
364{ 383{
365 struct snd_card *card = __card; 384 struct snd_card *card = __card;
@@ -405,6 +424,8 @@ int snd_card_free_in_thread(struct snd_card *card)
405 return -EFAULT; 424 return -EFAULT;
406} 425}
407 426
427EXPORT_SYMBOL(snd_card_free_in_thread);
428
408static void choose_default_id(struct snd_card *card) 429static void choose_default_id(struct snd_card *card)
409{ 430{
410 int i, len, idx_flag = 0, loops = SNDRV_CARDS; 431 int i, len, idx_flag = 0, loops = SNDRV_CARDS;
@@ -487,16 +508,16 @@ int snd_card_register(struct snd_card *card)
487 snd_assert(card != NULL, return -EINVAL); 508 snd_assert(card != NULL, return -EINVAL);
488 if ((err = snd_device_register_all(card)) < 0) 509 if ((err = snd_device_register_all(card)) < 0)
489 return err; 510 return err;
490 write_lock(&snd_card_rwlock); 511 mutex_lock(&snd_card_mutex);
491 if (snd_cards[card->number]) { 512 if (snd_cards[card->number]) {
492 /* already registered */ 513 /* already registered */
493 write_unlock(&snd_card_rwlock); 514 mutex_unlock(&snd_card_mutex);
494 return 0; 515 return 0;
495 } 516 }
496 if (card->id[0] == '\0') 517 if (card->id[0] == '\0')
497 choose_default_id(card); 518 choose_default_id(card);
498 snd_cards[card->number] = card; 519 snd_cards[card->number] = card;
499 write_unlock(&snd_card_rwlock); 520 mutex_unlock(&snd_card_mutex);
500 init_info_for_card(card); 521 init_info_for_card(card);
501#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 522#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
502 if (snd_mixer_oss_notify_callback) 523 if (snd_mixer_oss_notify_callback)
@@ -505,8 +526,10 @@ int snd_card_register(struct snd_card *card)
505 return 0; 526 return 0;
506} 527}
507 528
529EXPORT_SYMBOL(snd_card_register);
530
508#ifdef CONFIG_PROC_FS 531#ifdef CONFIG_PROC_FS
509static struct snd_info_entry *snd_card_info_entry = NULL; 532static struct snd_info_entry *snd_card_info_entry;
510 533
511static void snd_card_info_read(struct snd_info_entry *entry, 534static void snd_card_info_read(struct snd_info_entry *entry,
512 struct snd_info_buffer *buffer) 535 struct snd_info_buffer *buffer)
@@ -515,7 +538,7 @@ static void snd_card_info_read(struct snd_info_entry *entry,
515 struct snd_card *card; 538 struct snd_card *card;
516 539
517 for (idx = count = 0; idx < SNDRV_CARDS; idx++) { 540 for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
518 read_lock(&snd_card_rwlock); 541 mutex_lock(&snd_card_mutex);
519 if ((card = snd_cards[idx]) != NULL) { 542 if ((card = snd_cards[idx]) != NULL) {
520 count++; 543 count++;
521 snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n", 544 snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n",
@@ -526,7 +549,7 @@ static void snd_card_info_read(struct snd_info_entry *entry,
526 snd_iprintf(buffer, " %s\n", 549 snd_iprintf(buffer, " %s\n",
527 card->longname); 550 card->longname);
528 } 551 }
529 read_unlock(&snd_card_rwlock); 552 mutex_unlock(&snd_card_mutex);
530 } 553 }
531 if (!count) 554 if (!count)
532 snd_iprintf(buffer, "--- no soundcards ---\n"); 555 snd_iprintf(buffer, "--- no soundcards ---\n");
@@ -540,12 +563,12 @@ void snd_card_info_read_oss(struct snd_info_buffer *buffer)
540 struct snd_card *card; 563 struct snd_card *card;
541 564
542 for (idx = count = 0; idx < SNDRV_CARDS; idx++) { 565 for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
543 read_lock(&snd_card_rwlock); 566 mutex_lock(&snd_card_mutex);
544 if ((card = snd_cards[idx]) != NULL) { 567 if ((card = snd_cards[idx]) != NULL) {
545 count++; 568 count++;
546 snd_iprintf(buffer, "%s\n", card->longname); 569 snd_iprintf(buffer, "%s\n", card->longname);
547 } 570 }
548 read_unlock(&snd_card_rwlock); 571 mutex_unlock(&snd_card_mutex);
549 } 572 }
550 if (!count) { 573 if (!count) {
551 snd_iprintf(buffer, "--- no soundcards ---\n"); 574 snd_iprintf(buffer, "--- no soundcards ---\n");
@@ -563,11 +586,11 @@ static void snd_card_module_info_read(struct snd_info_entry *entry,
563 struct snd_card *card; 586 struct snd_card *card;
564 587
565 for (idx = 0; idx < SNDRV_CARDS; idx++) { 588 for (idx = 0; idx < SNDRV_CARDS; idx++) {
566 read_lock(&snd_card_rwlock); 589 mutex_lock(&snd_card_mutex);
567 if ((card = snd_cards[idx]) != NULL) 590 if ((card = snd_cards[idx]) != NULL)
568 snd_iprintf(buffer, "%2i %s\n", 591 snd_iprintf(buffer, "%2i %s\n",
569 idx, card->module->name); 592 idx, card->module->name);
570 read_unlock(&snd_card_rwlock); 593 mutex_unlock(&snd_card_mutex);
571 } 594 }
572} 595}
573#endif 596#endif
@@ -579,7 +602,6 @@ int __init snd_card_info_init(void)
579 entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL); 602 entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL);
580 if (! entry) 603 if (! entry)
581 return -ENOMEM; 604 return -ENOMEM;
582 entry->c.text.read_size = PAGE_SIZE;
583 entry->c.text.read = snd_card_info_read; 605 entry->c.text.read = snd_card_info_read;
584 if (snd_info_register(entry) < 0) { 606 if (snd_info_register(entry) < 0) {
585 snd_info_free_entry(entry); 607 snd_info_free_entry(entry);
@@ -590,7 +612,6 @@ int __init snd_card_info_init(void)
590#ifdef MODULE 612#ifdef MODULE
591 entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL); 613 entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL);
592 if (entry) { 614 if (entry) {
593 entry->c.text.read_size = PAGE_SIZE;
594 entry->c.text.read = snd_card_module_info_read; 615 entry->c.text.read = snd_card_module_info_read;
595 if (snd_info_register(entry) < 0) 616 if (snd_info_register(entry) < 0)
596 snd_info_free_entry(entry); 617 snd_info_free_entry(entry);
@@ -644,6 +665,8 @@ int snd_component_add(struct snd_card *card, const char *component)
644 return 0; 665 return 0;
645} 666}
646 667
668EXPORT_SYMBOL(snd_component_add);
669
647/** 670/**
648 * snd_card_file_add - add the file to the file list of the card 671 * snd_card_file_add - add the file to the file list of the card
649 * @card: soundcard structure 672 * @card: soundcard structure
@@ -676,6 +699,8 @@ int snd_card_file_add(struct snd_card *card, struct file *file)
676 return 0; 699 return 0;
677} 700}
678 701
702EXPORT_SYMBOL(snd_card_file_add);
703
679/** 704/**
680 * snd_card_file_remove - remove the file from the file list 705 * snd_card_file_remove - remove the file from the file list
681 * @card: soundcard structure 706 * @card: soundcard structure
@@ -717,6 +742,8 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
717 return 0; 742 return 0;
718} 743}
719 744
745EXPORT_SYMBOL(snd_card_file_remove);
746
720#ifdef CONFIG_PM 747#ifdef CONFIG_PM
721/** 748/**
722 * snd_power_wait - wait until the power-state is changed. 749 * snd_power_wait - wait until the power-state is changed.
@@ -753,4 +780,5 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state)
753 return result; 780 return result;
754} 781}
755 782
783EXPORT_SYMBOL(snd_power_wait);
756#endif /* CONFIG_PM */ 784#endif /* CONFIG_PM */
diff --git a/sound/core/isadma.c b/sound/core/isadma.c
index 1a378951da5b..d52398727f0a 100644
--- a/sound/core/isadma.c
+++ b/sound/core/isadma.c
@@ -56,6 +56,8 @@ void snd_dma_program(unsigned long dma,
56 release_dma_lock(flags); 56 release_dma_lock(flags);
57} 57}
58 58
59EXPORT_SYMBOL(snd_dma_program);
60
59/** 61/**
60 * snd_dma_disable - stop the ISA DMA transfer 62 * snd_dma_disable - stop the ISA DMA transfer
61 * @dma: the dma number 63 * @dma: the dma number
@@ -72,6 +74,8 @@ void snd_dma_disable(unsigned long dma)
72 release_dma_lock(flags); 74 release_dma_lock(flags);
73} 75}
74 76
77EXPORT_SYMBOL(snd_dma_disable);
78
75/** 79/**
76 * snd_dma_pointer - return the current pointer to DMA transfer buffer in bytes 80 * snd_dma_pointer - return the current pointer to DMA transfer buffer in bytes
77 * @dma: the dma number 81 * @dma: the dma number
@@ -101,3 +105,5 @@ unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
101 else 105 else
102 return size - result; 106 return size - result;
103} 107}
108
109EXPORT_SYMBOL(snd_dma_pointer);
diff --git a/sound/core/memory.c b/sound/core/memory.c
index 862d62d2e144..fe59850be868 100644
--- a/sound/core/memory.c
+++ b/sound/core/memory.c
@@ -21,6 +21,7 @@
21 */ 21 */
22 22
23#include <linux/config.h> 23#include <linux/config.h>
24#include <linux/module.h>
24#include <asm/io.h> 25#include <asm/io.h>
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26 27
@@ -55,6 +56,8 @@ int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size
55#endif 56#endif
56} 57}
57 58
59EXPORT_SYMBOL(copy_to_user_fromio);
60
58/** 61/**
59 * copy_from_user_toio - copy data from user-space to mmio-space 62 * copy_from_user_toio - copy data from user-space to mmio-space
60 * @dst: the destination pointer on mmio-space 63 * @dst: the destination pointer on mmio-space
@@ -85,3 +88,5 @@ int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size
85 return 0; 88 return 0;
86#endif 89#endif
87} 90}
91
92EXPORT_SYMBOL(copy_from_user_toio);
diff --git a/sound/core/misc.c b/sound/core/misc.c
index b53e563c09e6..03fc711f4127 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -34,6 +34,8 @@ void release_and_free_resource(struct resource *res)
34 } 34 }
35} 35}
36 36
37EXPORT_SYMBOL(release_and_free_resource);
38
37#ifdef CONFIG_SND_VERBOSE_PRINTK 39#ifdef CONFIG_SND_VERBOSE_PRINTK
38void snd_verbose_printk(const char *file, int line, const char *format, ...) 40void snd_verbose_printk(const char *file, int line, const char *format, ...)
39{ 41{
@@ -51,6 +53,8 @@ void snd_verbose_printk(const char *file, int line, const char *format, ...)
51 vprintk(format, args); 53 vprintk(format, args);
52 va_end(args); 54 va_end(args);
53} 55}
56
57EXPORT_SYMBOL(snd_verbose_printk);
54#endif 58#endif
55 59
56#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK) 60#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
@@ -71,4 +75,6 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
71 va_end(args); 75 va_end(args);
72 76
73} 77}
78
79EXPORT_SYMBOL(snd_verbose_printd);
74#endif 80#endif
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 9c68bc3f97aa..71b5080fa66d 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1182,9 +1182,7 @@ static void snd_mixer_oss_proc_init(struct snd_mixer_oss *mixer)
1182 return; 1182 return;
1183 entry->content = SNDRV_INFO_CONTENT_TEXT; 1183 entry->content = SNDRV_INFO_CONTENT_TEXT;
1184 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 1184 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
1185 entry->c.text.read_size = 8192;
1186 entry->c.text.read = snd_mixer_oss_proc_read; 1185 entry->c.text.read = snd_mixer_oss_proc_read;
1187 entry->c.text.write_size = 8192;
1188 entry->c.text.write = snd_mixer_oss_proc_write; 1186 entry->c.text.write = snd_mixer_oss_proc_write;
1189 entry->private_data = mixer; 1187 entry->private_data = mixer;
1190 if (snd_info_register(entry) < 0) { 1188 if (snd_info_register(entry) < 0) {
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index ac990bf0b48f..f5ff4f4a16ee 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -45,7 +45,7 @@
45 45
46#define OSS_ALSAEMULVER _SIOR ('M', 249, int) 46#define OSS_ALSAEMULVER _SIOR ('M', 249, int)
47 47
48static int dsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0}; 48static int dsp_map[SNDRV_CARDS];
49static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; 49static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
50static int nonblock_open = 1; 50static int nonblock_open = 1;
51 51
@@ -78,6 +78,487 @@ static inline void snd_leave_user(mm_segment_t fs)
78 set_fs(fs); 78 set_fs(fs);
79} 79}
80 80
81/*
82 * helper functions to process hw_params
83 */
84static int snd_interval_refine_min(struct snd_interval *i, unsigned int min, int openmin)
85{
86 int changed = 0;
87 if (i->min < min) {
88 i->min = min;
89 i->openmin = openmin;
90 changed = 1;
91 } else if (i->min == min && !i->openmin && openmin) {
92 i->openmin = 1;
93 changed = 1;
94 }
95 if (i->integer) {
96 if (i->openmin) {
97 i->min++;
98 i->openmin = 0;
99 }
100 }
101 if (snd_interval_checkempty(i)) {
102 snd_interval_none(i);
103 return -EINVAL;
104 }
105 return changed;
106}
107
108static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int openmax)
109{
110 int changed = 0;
111 if (i->max > max) {
112 i->max = max;
113 i->openmax = openmax;
114 changed = 1;
115 } else if (i->max == max && !i->openmax && openmax) {
116 i->openmax = 1;
117 changed = 1;
118 }
119 if (i->integer) {
120 if (i->openmax) {
121 i->max--;
122 i->openmax = 0;
123 }
124 }
125 if (snd_interval_checkempty(i)) {
126 snd_interval_none(i);
127 return -EINVAL;
128 }
129 return changed;
130}
131
132static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
133{
134 struct snd_interval t;
135 t.empty = 0;
136 t.min = t.max = val;
137 t.openmin = t.openmax = 0;
138 t.integer = 1;
139 return snd_interval_refine(i, &t);
140}
141
142/**
143 * snd_pcm_hw_param_value_min
144 * @params: the hw_params instance
145 * @var: parameter to retrieve
146 * @dir: pointer to the direction (-1,0,1) or NULL
147 *
148 * Return the minimum value for field PAR.
149 */
150static unsigned int
151snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
152 snd_pcm_hw_param_t var, int *dir)
153{
154 if (hw_is_mask(var)) {
155 if (dir)
156 *dir = 0;
157 return snd_mask_min(hw_param_mask_c(params, var));
158 }
159 if (hw_is_interval(var)) {
160 const struct snd_interval *i = hw_param_interval_c(params, var);
161 if (dir)
162 *dir = i->openmin;
163 return snd_interval_min(i);
164 }
165 return -EINVAL;
166}
167
168/**
169 * snd_pcm_hw_param_value_max
170 * @params: the hw_params instance
171 * @var: parameter to retrieve
172 * @dir: pointer to the direction (-1,0,1) or NULL
173 *
174 * Return the maximum value for field PAR.
175 */
176static unsigned int
177snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
178 snd_pcm_hw_param_t var, int *dir)
179{
180 if (hw_is_mask(var)) {
181 if (dir)
182 *dir = 0;
183 return snd_mask_max(hw_param_mask_c(params, var));
184 }
185 if (hw_is_interval(var)) {
186 const struct snd_interval *i = hw_param_interval_c(params, var);
187 if (dir)
188 *dir = - (int) i->openmax;
189 return snd_interval_max(i);
190 }
191 return -EINVAL;
192}
193
194static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params,
195 snd_pcm_hw_param_t var,
196 const struct snd_mask *val)
197{
198 int changed;
199 changed = snd_mask_refine(hw_param_mask(params, var), val);
200 if (changed) {
201 params->cmask |= 1 << var;
202 params->rmask |= 1 << var;
203 }
204 return changed;
205}
206
207static int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm,
208 struct snd_pcm_hw_params *params,
209 snd_pcm_hw_param_t var,
210 const struct snd_mask *val)
211{
212 int changed = _snd_pcm_hw_param_mask(params, var, val);
213 if (changed < 0)
214 return changed;
215 if (params->rmask) {
216 int err = snd_pcm_hw_refine(pcm, params);
217 if (err < 0)
218 return err;
219 }
220 return 0;
221}
222
223static int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params,
224 snd_pcm_hw_param_t var, unsigned int val,
225 int dir)
226{
227 int changed;
228 int open = 0;
229 if (dir) {
230 if (dir > 0) {
231 open = 1;
232 } else if (dir < 0) {
233 if (val > 0) {
234 open = 1;
235 val--;
236 }
237 }
238 }
239 if (hw_is_mask(var))
240 changed = snd_mask_refine_min(hw_param_mask(params, var),
241 val + !!open);
242 else if (hw_is_interval(var))
243 changed = snd_interval_refine_min(hw_param_interval(params, var),
244 val, open);
245 else
246 return -EINVAL;
247 if (changed) {
248 params->cmask |= 1 << var;
249 params->rmask |= 1 << var;
250 }
251 return changed;
252}
253
254/**
255 * snd_pcm_hw_param_min
256 * @pcm: PCM instance
257 * @params: the hw_params instance
258 * @var: parameter to retrieve
259 * @val: minimal value
260 * @dir: pointer to the direction (-1,0,1) or NULL
261 *
262 * Inside configuration space defined by PARAMS remove from PAR all
263 * values < VAL. Reduce configuration space accordingly.
264 * Return new minimum or -EINVAL if the configuration space is empty
265 */
266static int snd_pcm_hw_param_min(struct snd_pcm_substream *pcm,
267 struct snd_pcm_hw_params *params,
268 snd_pcm_hw_param_t var, unsigned int val,
269 int *dir)
270{
271 int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0);
272 if (changed < 0)
273 return changed;
274 if (params->rmask) {
275 int err = snd_pcm_hw_refine(pcm, params);
276 if (err < 0)
277 return err;
278 }
279 return snd_pcm_hw_param_value_min(params, var, dir);
280}
281
282static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params,
283 snd_pcm_hw_param_t var, unsigned int val,
284 int dir)
285{
286 int changed;
287 int open = 0;
288 if (dir) {
289 if (dir < 0) {
290 open = 1;
291 } else if (dir > 0) {
292 open = 1;
293 val++;
294 }
295 }
296 if (hw_is_mask(var)) {
297 if (val == 0 && open) {
298 snd_mask_none(hw_param_mask(params, var));
299 changed = -EINVAL;
300 } else
301 changed = snd_mask_refine_max(hw_param_mask(params, var),
302 val - !!open);
303 } else if (hw_is_interval(var))
304 changed = snd_interval_refine_max(hw_param_interval(params, var),
305 val, open);
306 else
307 return -EINVAL;
308 if (changed) {
309 params->cmask |= 1 << var;
310 params->rmask |= 1 << var;
311 }
312 return changed;
313}
314
315/**
316 * snd_pcm_hw_param_max
317 * @pcm: PCM instance
318 * @params: the hw_params instance
319 * @var: parameter to retrieve
320 * @val: maximal value
321 * @dir: pointer to the direction (-1,0,1) or NULL
322 *
323 * Inside configuration space defined by PARAMS remove from PAR all
324 * values >= VAL + 1. Reduce configuration space accordingly.
325 * Return new maximum or -EINVAL if the configuration space is empty
326 */
327static int snd_pcm_hw_param_max(struct snd_pcm_substream *pcm,
328 struct snd_pcm_hw_params *params,
329 snd_pcm_hw_param_t var, unsigned int val,
330 int *dir)
331{
332 int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0);
333 if (changed < 0)
334 return changed;
335 if (params->rmask) {
336 int err = snd_pcm_hw_refine(pcm, params);
337 if (err < 0)
338 return err;
339 }
340 return snd_pcm_hw_param_value_max(params, var, dir);
341}
342
343static int boundary_sub(int a, int adir,
344 int b, int bdir,
345 int *c, int *cdir)
346{
347 adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0);
348 bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0);
349 *c = a - b;
350 *cdir = adir - bdir;
351 if (*cdir == -2) {
352 (*c)--;
353 } else if (*cdir == 2) {
354 (*c)++;
355 }
356 return 0;
357}
358
359static int boundary_lt(unsigned int a, int adir,
360 unsigned int b, int bdir)
361{
362 if (adir < 0) {
363 a--;
364 adir = 1;
365 } else if (adir > 0)
366 adir = 1;
367 if (bdir < 0) {
368 b--;
369 bdir = 1;
370 } else if (bdir > 0)
371 bdir = 1;
372 return a < b || (a == b && adir < bdir);
373}
374
375/* Return 1 if min is nearer to best than max */
376static int boundary_nearer(int min, int mindir,
377 int best, int bestdir,
378 int max, int maxdir)
379{
380 int dmin, dmindir;
381 int dmax, dmaxdir;
382 boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir);
383 boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir);
384 return boundary_lt(dmin, dmindir, dmax, dmaxdir);
385}
386
387/**
388 * snd_pcm_hw_param_near
389 * @pcm: PCM instance
390 * @params: the hw_params instance
391 * @var: parameter to retrieve
392 * @best: value to set
393 * @dir: pointer to the direction (-1,0,1) or NULL
394 *
395 * Inside configuration space defined by PARAMS set PAR to the available value
396 * nearest to VAL. Reduce configuration space accordingly.
397 * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS,
398 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
399 * Return the value found.
400 */
401static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
402 struct snd_pcm_hw_params *params,
403 snd_pcm_hw_param_t var, unsigned int best,
404 int *dir)
405{
406 struct snd_pcm_hw_params *save = NULL;
407 int v;
408 unsigned int saved_min;
409 int last = 0;
410 int min, max;
411 int mindir, maxdir;
412 int valdir = dir ? *dir : 0;
413 /* FIXME */
414 if (best > INT_MAX)
415 best = INT_MAX;
416 min = max = best;
417 mindir = maxdir = valdir;
418 if (maxdir > 0)
419 maxdir = 0;
420 else if (maxdir == 0)
421 maxdir = -1;
422 else {
423 maxdir = 1;
424 max--;
425 }
426 save = kmalloc(sizeof(*save), GFP_KERNEL);
427 if (save == NULL)
428 return -ENOMEM;
429 *save = *params;
430 saved_min = min;
431 min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
432 if (min >= 0) {
433 struct snd_pcm_hw_params *params1;
434 if (max < 0)
435 goto _end;
436 if ((unsigned int)min == saved_min && mindir == valdir)
437 goto _end;
438 params1 = kmalloc(sizeof(*params1), GFP_KERNEL);
439 if (params1 == NULL) {
440 kfree(save);
441 return -ENOMEM;
442 }
443 *params1 = *save;
444 max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir);
445 if (max < 0) {
446 kfree(params1);
447 goto _end;
448 }
449 if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) {
450 *params = *params1;
451 last = 1;
452 }
453 kfree(params1);
454 } else {
455 *params = *save;
456 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
457 snd_assert(max >= 0, return -EINVAL);
458 last = 1;
459 }
460 _end:
461 kfree(save);
462 if (last)
463 v = snd_pcm_hw_param_last(pcm, params, var, dir);
464 else
465 v = snd_pcm_hw_param_first(pcm, params, var, dir);
466 snd_assert(v >= 0, return -EINVAL);
467 return v;
468}
469
470static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
471 snd_pcm_hw_param_t var, unsigned int val,
472 int dir)
473{
474 int changed;
475 if (hw_is_mask(var)) {
476 struct snd_mask *m = hw_param_mask(params, var);
477 if (val == 0 && dir < 0) {
478 changed = -EINVAL;
479 snd_mask_none(m);
480 } else {
481 if (dir > 0)
482 val++;
483 else if (dir < 0)
484 val--;
485 changed = snd_mask_refine_set(hw_param_mask(params, var), val);
486 }
487 } else if (hw_is_interval(var)) {
488 struct snd_interval *i = hw_param_interval(params, var);
489 if (val == 0 && dir < 0) {
490 changed = -EINVAL;
491 snd_interval_none(i);
492 } else if (dir == 0)
493 changed = snd_interval_refine_set(i, val);
494 else {
495 struct snd_interval t;
496 t.openmin = 1;
497 t.openmax = 1;
498 t.empty = 0;
499 t.integer = 0;
500 if (dir < 0) {
501 t.min = val - 1;
502 t.max = val;
503 } else {
504 t.min = val;
505 t.max = val+1;
506 }
507 changed = snd_interval_refine(i, &t);
508 }
509 } else
510 return -EINVAL;
511 if (changed) {
512 params->cmask |= 1 << var;
513 params->rmask |= 1 << var;
514 }
515 return changed;
516}
517
518/**
519 * snd_pcm_hw_param_set
520 * @pcm: PCM instance
521 * @params: the hw_params instance
522 * @var: parameter to retrieve
523 * @val: value to set
524 * @dir: pointer to the direction (-1,0,1) or NULL
525 *
526 * Inside configuration space defined by PARAMS remove from PAR all
527 * values != VAL. Reduce configuration space accordingly.
528 * Return VAL or -EINVAL if the configuration space is empty
529 */
530static int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm,
531 struct snd_pcm_hw_params *params,
532 snd_pcm_hw_param_t var, unsigned int val,
533 int dir)
534{
535 int changed = _snd_pcm_hw_param_set(params, var, val, dir);
536 if (changed < 0)
537 return changed;
538 if (params->rmask) {
539 int err = snd_pcm_hw_refine(pcm, params);
540 if (err < 0)
541 return err;
542 }
543 return snd_pcm_hw_param_value(params, var, NULL);
544}
545
546static int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params,
547 snd_pcm_hw_param_t var)
548{
549 int changed;
550 changed = snd_interval_setinteger(hw_param_interval(params, var));
551 if (changed) {
552 params->cmask |= 1 << var;
553 params->rmask |= 1 << var;
554 }
555 return changed;
556}
557
558/*
559 * plugin
560 */
561
81#ifdef CONFIG_SND_PCM_OSS_PLUGINS 562#ifdef CONFIG_SND_PCM_OSS_PLUGINS
82static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream) 563static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream)
83{ 564{
@@ -203,7 +684,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
203 oss_buffer_size = snd_pcm_plug_client_size(substream, 684 oss_buffer_size = snd_pcm_plug_client_size(substream,
204 snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size; 685 snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size;
205 oss_buffer_size = 1 << ld2(oss_buffer_size); 686 oss_buffer_size = 1 << ld2(oss_buffer_size);
206 if (atomic_read(&runtime->mmap_count)) { 687 if (atomic_read(&substream->mmap_count)) {
207 if (oss_buffer_size > runtime->oss.mmap_bytes) 688 if (oss_buffer_size > runtime->oss.mmap_bytes)
208 oss_buffer_size = runtime->oss.mmap_bytes; 689 oss_buffer_size = runtime->oss.mmap_bytes;
209 } 690 }
@@ -338,7 +819,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
338 goto failure; 819 goto failure;
339 } 820 }
340 821
341 if (atomic_read(&runtime->mmap_count)) 822 if (atomic_read(&substream->mmap_count))
342 direct = 1; 823 direct = 1;
343 else 824 else
344 direct = substream->oss.setup.direct; 825 direct = substream->oss.setup.direct;
@@ -347,7 +828,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
347 _snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS); 828 _snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS);
348 _snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0); 829 _snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0);
349 snd_mask_none(&mask); 830 snd_mask_none(&mask);
350 if (atomic_read(&runtime->mmap_count)) 831 if (atomic_read(&substream->mmap_count))
351 snd_mask_set(&mask, SNDRV_PCM_ACCESS_MMAP_INTERLEAVED); 832 snd_mask_set(&mask, SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
352 else { 833 else {
353 snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_INTERLEAVED); 834 snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_INTERLEAVED);
@@ -466,7 +947,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
466 } else { 947 } else {
467 sw_params->start_threshold = runtime->boundary; 948 sw_params->start_threshold = runtime->boundary;
468 } 949 }
469 if (atomic_read(&runtime->mmap_count) || substream->stream == SNDRV_PCM_STREAM_CAPTURE) 950 if (atomic_read(&substream->mmap_count) ||
951 substream->stream == SNDRV_PCM_STREAM_CAPTURE)
470 sw_params->stop_threshold = runtime->boundary; 952 sw_params->stop_threshold = runtime->boundary;
471 else 953 else
472 sw_params->stop_threshold = runtime->buffer_size; 954 sw_params->stop_threshold = runtime->buffer_size;
@@ -476,7 +958,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
476 sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 958 sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
477 1 : runtime->period_size; 959 1 : runtime->period_size;
478 sw_params->xfer_align = 1; 960 sw_params->xfer_align = 1;
479 if (atomic_read(&runtime->mmap_count) || 961 if (atomic_read(&substream->mmap_count) ||
480 substream->oss.setup.nosilence) { 962 substream->oss.setup.nosilence) {
481 sw_params->silence_threshold = 0; 963 sw_params->silence_threshold = 0;
482 sw_params->silence_size = 0; 964 sw_params->silence_size = 0;
@@ -820,7 +1302,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
820 ssize_t tmp; 1302 ssize_t tmp;
821 struct snd_pcm_runtime *runtime = substream->runtime; 1303 struct snd_pcm_runtime *runtime = substream->runtime;
822 1304
823 if (atomic_read(&runtime->mmap_count)) 1305 if (atomic_read(&substream->mmap_count))
824 return -ENXIO; 1306 return -ENXIO;
825 1307
826 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) 1308 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
@@ -850,7 +1332,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
850 if (runtime->oss.period_ptr == 0 || 1332 if (runtime->oss.period_ptr == 0 ||
851 runtime->oss.period_ptr == runtime->oss.buffer_used) 1333 runtime->oss.period_ptr == runtime->oss.buffer_used)
852 runtime->oss.buffer_used = 0; 1334 runtime->oss.buffer_used = 0;
853 else if ((substream->ffile->f_flags & O_NONBLOCK) != 0) 1335 else if ((substream->f_flags & O_NONBLOCK) != 0)
854 return xfer > 0 ? xfer : -EAGAIN; 1336 return xfer > 0 ? xfer : -EAGAIN;
855 } 1337 }
856 } else { 1338 } else {
@@ -863,7 +1345,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
863 buf += tmp; 1345 buf += tmp;
864 bytes -= tmp; 1346 bytes -= tmp;
865 xfer += tmp; 1347 xfer += tmp;
866 if ((substream->ffile->f_flags & O_NONBLOCK) != 0 && 1348 if ((substream->f_flags & O_NONBLOCK) != 0 &&
867 tmp != runtime->oss.period_bytes) 1349 tmp != runtime->oss.period_bytes)
868 break; 1350 break;
869 } 1351 }
@@ -910,7 +1392,7 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
910 ssize_t tmp; 1392 ssize_t tmp;
911 struct snd_pcm_runtime *runtime = substream->runtime; 1393 struct snd_pcm_runtime *runtime = substream->runtime;
912 1394
913 if (atomic_read(&runtime->mmap_count)) 1395 if (atomic_read(&substream->mmap_count))
914 return -ENXIO; 1396 return -ENXIO;
915 1397
916 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) 1398 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
@@ -1040,7 +1522,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1040 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; 1522 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
1041 if (substream != NULL) { 1523 if (substream != NULL) {
1042 runtime = substream->runtime; 1524 runtime = substream->runtime;
1043 if (atomic_read(&runtime->mmap_count)) 1525 if (atomic_read(&substream->mmap_count))
1044 goto __direct; 1526 goto __direct;
1045 if ((err = snd_pcm_oss_make_ready(substream)) < 0) 1527 if ((err = snd_pcm_oss_make_ready(substream)) < 0)
1046 return err; 1528 return err;
@@ -1101,10 +1583,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1101 * finish sync: drain the buffer 1583 * finish sync: drain the buffer
1102 */ 1584 */
1103 __direct: 1585 __direct:
1104 saved_f_flags = substream->ffile->f_flags; 1586 saved_f_flags = substream->f_flags;
1105 substream->ffile->f_flags &= ~O_NONBLOCK; 1587 substream->f_flags &= ~O_NONBLOCK;
1106 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); 1588 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
1107 substream->ffile->f_flags = saved_f_flags; 1589 substream->f_flags = saved_f_flags;
1108 if (err < 0) 1590 if (err < 0)
1109 return err; 1591 return err;
1110 runtime->oss.prepare = 1; 1592 runtime->oss.prepare = 1;
@@ -1209,7 +1691,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
1209 1691
1210 if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0) 1692 if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
1211 return err; 1693 return err;
1212 if (atomic_read(&substream->runtime->mmap_count)) 1694 if (atomic_read(&substream->mmap_count))
1213 direct = 1; 1695 direct = 1;
1214 else 1696 else
1215 direct = substream->oss.setup.direct; 1697 direct = substream->oss.setup.direct;
@@ -1419,7 +1901,7 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1419 if (trigger & PCM_ENABLE_OUTPUT) { 1901 if (trigger & PCM_ENABLE_OUTPUT) {
1420 if (runtime->oss.trigger) 1902 if (runtime->oss.trigger)
1421 goto _skip1; 1903 goto _skip1;
1422 if (atomic_read(&psubstream->runtime->mmap_count)) 1904 if (atomic_read(&psubstream->mmap_count))
1423 snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt); 1905 snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt);
1424 runtime->oss.trigger = 1; 1906 runtime->oss.trigger = 1;
1425 runtime->start_threshold = 1; 1907 runtime->start_threshold = 1;
@@ -1537,7 +2019,7 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream
1537 if (err < 0) 2019 if (err < 0)
1538 return err; 2020 return err;
1539 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); 2021 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size);
1540 if (atomic_read(&runtime->mmap_count)) { 2022 if (atomic_read(&substream->mmap_count)) {
1541 snd_pcm_sframes_t n; 2023 snd_pcm_sframes_t n;
1542 n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt; 2024 n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt;
1543 if (n < 0) 2025 if (n < 0)
@@ -1683,9 +2165,9 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
1683 substream->oss.oss = 1; 2165 substream->oss.oss = 1;
1684 substream->oss.setup = *setup; 2166 substream->oss.setup = *setup;
1685 if (setup->nonblock) 2167 if (setup->nonblock)
1686 substream->ffile->f_flags |= O_NONBLOCK; 2168 substream->f_flags |= O_NONBLOCK;
1687 else if (setup->block) 2169 else if (setup->block)
1688 substream->ffile->f_flags &= ~O_NONBLOCK; 2170 substream->f_flags &= ~O_NONBLOCK;
1689 runtime = substream->runtime; 2171 runtime = substream->runtime;
1690 runtime->oss.params = 1; 2172 runtime->oss.params = 1;
1691 runtime->oss.trigger = 1; 2173 runtime->oss.trigger = 1;
@@ -1742,6 +2224,7 @@ static int snd_pcm_oss_open_file(struct file *file,
1742 (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX)) 2224 (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX))
1743 f_mode = FMODE_WRITE; 2225 f_mode = FMODE_WRITE;
1744 2226
2227 file->f_flags &= ~O_APPEND;
1745 for (idx = 0; idx < 2; idx++) { 2228 for (idx = 0; idx < 2; idx++) {
1746 if (setup[idx].disable) 2229 if (setup[idx].disable)
1747 continue; 2230 continue;
@@ -2059,6 +2542,7 @@ static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t coun
2059 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; 2542 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
2060 if (substream == NULL) 2543 if (substream == NULL)
2061 return -ENXIO; 2544 return -ENXIO;
2545 substream->f_flags = file->f_flags & O_NONBLOCK;
2062#ifndef OSS_DEBUG 2546#ifndef OSS_DEBUG
2063 return snd_pcm_oss_read1(substream, buf, count); 2547 return snd_pcm_oss_read1(substream, buf, count);
2064#else 2548#else
@@ -2080,6 +2564,7 @@ static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size
2080 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; 2564 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
2081 if (substream == NULL) 2565 if (substream == NULL)
2082 return -ENXIO; 2566 return -ENXIO;
2567 substream->f_flags = file->f_flags & O_NONBLOCK;
2083 result = snd_pcm_oss_write1(substream, buf, count); 2568 result = snd_pcm_oss_write1(substream, buf, count);
2084#ifdef OSS_DEBUG 2569#ifdef OSS_DEBUG
2085 printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result); 2570 printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result);
@@ -2090,7 +2575,7 @@ static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size
2090static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream) 2575static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
2091{ 2576{
2092 struct snd_pcm_runtime *runtime = substream->runtime; 2577 struct snd_pcm_runtime *runtime = substream->runtime;
2093 if (atomic_read(&runtime->mmap_count)) 2578 if (atomic_read(&substream->mmap_count))
2094 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2579 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt;
2095 else 2580 else
2096 return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames; 2581 return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames;
@@ -2099,7 +2584,7 @@ static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
2099static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream) 2584static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream)
2100{ 2585{
2101 struct snd_pcm_runtime *runtime = substream->runtime; 2586 struct snd_pcm_runtime *runtime = substream->runtime;
2102 if (atomic_read(&runtime->mmap_count)) 2587 if (atomic_read(&substream->mmap_count))
2103 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2588 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt;
2104 else 2589 else
2105 return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames; 2590 return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames;
@@ -2342,9 +2827,7 @@ static void snd_pcm_oss_proc_init(struct snd_pcm *pcm)
2342 if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) { 2827 if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) {
2343 entry->content = SNDRV_INFO_CONTENT_TEXT; 2828 entry->content = SNDRV_INFO_CONTENT_TEXT;
2344 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 2829 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
2345 entry->c.text.read_size = 8192;
2346 entry->c.text.read = snd_pcm_oss_proc_read; 2830 entry->c.text.read = snd_pcm_oss_proc_read;
2347 entry->c.text.write_size = 8192;
2348 entry->c.text.write = snd_pcm_oss_proc_write; 2831 entry->c.text.write = snd_pcm_oss_proc_write;
2349 entry->private_data = pstr; 2832 entry->private_data = pstr;
2350 if (snd_info_register(entry) < 0) { 2833 if (snd_info_register(entry) < 0) {
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 84b00038236d..7581edd7b9ff 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -351,10 +351,8 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
351 snd_iprintf(buffer, "closed\n"); 351 snd_iprintf(buffer, "closed\n");
352 return; 352 return;
353 } 353 }
354 snd_pcm_stream_lock_irq(substream);
355 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { 354 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
356 snd_iprintf(buffer, "no setup\n"); 355 snd_iprintf(buffer, "no setup\n");
357 snd_pcm_stream_unlock_irq(substream);
358 return; 356 return;
359 } 357 }
360 snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access)); 358 snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));
@@ -375,7 +373,6 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
375 snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames); 373 snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames);
376 } 374 }
377#endif 375#endif
378 snd_pcm_stream_unlock_irq(substream);
379} 376}
380 377
381static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, 378static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
@@ -387,10 +384,8 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
387 snd_iprintf(buffer, "closed\n"); 384 snd_iprintf(buffer, "closed\n");
388 return; 385 return;
389 } 386 }
390 snd_pcm_stream_lock_irq(substream);
391 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { 387 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
392 snd_iprintf(buffer, "no setup\n"); 388 snd_iprintf(buffer, "no setup\n");
393 snd_pcm_stream_unlock_irq(substream);
394 return; 389 return;
395 } 390 }
396 snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode)); 391 snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
@@ -403,7 +398,6 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
403 snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); 398 snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);
404 snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size); 399 snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);
405 snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary); 400 snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);
406 snd_pcm_stream_unlock_irq(substream);
407} 401}
408 402
409static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, 403static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
@@ -472,7 +466,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
472 pstr->proc_root = entry; 466 pstr->proc_root = entry;
473 467
474 if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) { 468 if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) {
475 snd_info_set_text_ops(entry, pstr, 256, snd_pcm_stream_proc_info_read); 469 snd_info_set_text_ops(entry, pstr, snd_pcm_stream_proc_info_read);
476 if (snd_info_register(entry) < 0) { 470 if (snd_info_register(entry) < 0) {
477 snd_info_free_entry(entry); 471 snd_info_free_entry(entry);
478 entry = NULL; 472 entry = NULL;
@@ -483,9 +477,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
483#ifdef CONFIG_SND_PCM_XRUN_DEBUG 477#ifdef CONFIG_SND_PCM_XRUN_DEBUG
484 if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug", 478 if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
485 pstr->proc_root)) != NULL) { 479 pstr->proc_root)) != NULL) {
486 entry->c.text.read_size = 64;
487 entry->c.text.read = snd_pcm_xrun_debug_read; 480 entry->c.text.read = snd_pcm_xrun_debug_read;
488 entry->c.text.write_size = 64;
489 entry->c.text.write = snd_pcm_xrun_debug_write; 481 entry->c.text.write = snd_pcm_xrun_debug_write;
490 entry->mode |= S_IWUSR; 482 entry->mode |= S_IWUSR;
491 entry->private_data = pstr; 483 entry->private_data = pstr;
@@ -537,7 +529,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
537 substream->proc_root = entry; 529 substream->proc_root = entry;
538 530
539 if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) { 531 if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) {
540 snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_info_read); 532 snd_info_set_text_ops(entry, substream,
533 snd_pcm_substream_proc_info_read);
541 if (snd_info_register(entry) < 0) { 534 if (snd_info_register(entry) < 0) {
542 snd_info_free_entry(entry); 535 snd_info_free_entry(entry);
543 entry = NULL; 536 entry = NULL;
@@ -546,7 +539,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
546 substream->proc_info_entry = entry; 539 substream->proc_info_entry = entry;
547 540
548 if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) { 541 if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) {
549 snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_hw_params_read); 542 snd_info_set_text_ops(entry, substream,
543 snd_pcm_substream_proc_hw_params_read);
550 if (snd_info_register(entry) < 0) { 544 if (snd_info_register(entry) < 0) {
551 snd_info_free_entry(entry); 545 snd_info_free_entry(entry);
552 entry = NULL; 546 entry = NULL;
@@ -555,7 +549,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
555 substream->proc_hw_params_entry = entry; 549 substream->proc_hw_params_entry = entry;
556 550
557 if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) { 551 if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) {
558 snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_sw_params_read); 552 snd_info_set_text_ops(entry, substream,
553 snd_pcm_substream_proc_sw_params_read);
559 if (snd_info_register(entry) < 0) { 554 if (snd_info_register(entry) < 0) {
560 snd_info_free_entry(entry); 555 snd_info_free_entry(entry);
561 entry = NULL; 556 entry = NULL;
@@ -564,7 +559,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
564 substream->proc_sw_params_entry = entry; 559 substream->proc_sw_params_entry = entry;
565 560
566 if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) { 561 if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) {
567 snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_status_read); 562 snd_info_set_text_ops(entry, substream,
563 snd_pcm_substream_proc_status_read);
568 if (snd_info_register(entry) < 0) { 564 if (snd_info_register(entry) < 0) {
569 snd_info_free_entry(entry); 565 snd_info_free_entry(entry);
570 entry = NULL; 566 entry = NULL;
@@ -666,11 +662,14 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
666 INIT_LIST_HEAD(&substream->self_group.substreams); 662 INIT_LIST_HEAD(&substream->self_group.substreams);
667 list_add_tail(&substream->link_list, &substream->self_group.substreams); 663 list_add_tail(&substream->link_list, &substream->self_group.substreams);
668 spin_lock_init(&substream->timer_lock); 664 spin_lock_init(&substream->timer_lock);
665 atomic_set(&substream->mmap_count, 0);
669 prev = substream; 666 prev = substream;
670 } 667 }
671 return 0; 668 return 0;
672} 669}
673 670
671EXPORT_SYMBOL(snd_pcm_new_stream);
672
674/** 673/**
675 * snd_pcm_new - create a new PCM instance 674 * snd_pcm_new - create a new PCM instance
676 * @card: the card instance 675 * @card: the card instance
@@ -730,6 +729,8 @@ int snd_pcm_new(struct snd_card *card, char *id, int device,
730 return 0; 729 return 0;
731} 730}
732 731
732EXPORT_SYMBOL(snd_pcm_new);
733
733static void snd_pcm_free_stream(struct snd_pcm_str * pstr) 734static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
734{ 735{
735 struct snd_pcm_substream *substream, *substream_next; 736 struct snd_pcm_substream *substream, *substream_next;
@@ -829,6 +830,26 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
829 return -EINVAL; 830 return -EINVAL;
830 } 831 }
831 832
833 if (file->f_flags & O_APPEND) {
834 if (prefer_subdevice < 0) {
835 if (pstr->substream_count > 1)
836 return -EINVAL; /* must be unique */
837 substream = pstr->substream;
838 } else {
839 for (substream = pstr->substream; substream;
840 substream = substream->next)
841 if (substream->number == prefer_subdevice)
842 break;
843 }
844 if (! substream)
845 return -ENODEV;
846 if (! SUBSTREAM_BUSY(substream))
847 return -EBADFD;
848 substream->ref_count++;
849 *rsubstream = substream;
850 return 0;
851 }
852
832 if (prefer_subdevice >= 0) { 853 if (prefer_subdevice >= 0) {
833 for (substream = pstr->substream; substream; substream = substream->next) 854 for (substream = pstr->substream; substream; substream = substream->next)
834 if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice) 855 if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice)
@@ -864,7 +885,6 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
864 memset((void*)runtime->control, 0, size); 885 memset((void*)runtime->control, 0, size);
865 886
866 init_waitqueue_head(&runtime->sleep); 887 init_waitqueue_head(&runtime->sleep);
867 atomic_set(&runtime->mmap_count, 0);
868 init_timer(&runtime->tick_timer); 888 init_timer(&runtime->tick_timer);
869 runtime->tick_timer.function = snd_pcm_tick_timer_func; 889 runtime->tick_timer.function = snd_pcm_tick_timer_func;
870 runtime->tick_timer.data = (unsigned long) substream; 890 runtime->tick_timer.data = (unsigned long) substream;
@@ -873,7 +893,8 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
873 893
874 substream->runtime = runtime; 894 substream->runtime = runtime;
875 substream->private_data = pcm->private_data; 895 substream->private_data = pcm->private_data;
876 substream->ffile = file; 896 substream->ref_count = 1;
897 substream->f_flags = file->f_flags;
877 pstr->substream_opened++; 898 pstr->substream_opened++;
878 *rsubstream = substream; 899 *rsubstream = substream;
879 return 0; 900 return 0;
@@ -882,7 +903,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
882void snd_pcm_detach_substream(struct snd_pcm_substream *substream) 903void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
883{ 904{
884 struct snd_pcm_runtime *runtime; 905 struct snd_pcm_runtime *runtime;
885 substream->file = NULL; 906
886 runtime = substream->runtime; 907 runtime = substream->runtime;
887 snd_assert(runtime != NULL, return); 908 snd_assert(runtime != NULL, return);
888 if (runtime->private_free != NULL) 909 if (runtime->private_free != NULL)
@@ -1022,6 +1043,8 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
1022 return 0; 1043 return 0;
1023} 1044}
1024 1045
1046EXPORT_SYMBOL(snd_pcm_notify);
1047
1025#ifdef CONFIG_PROC_FS 1048#ifdef CONFIG_PROC_FS
1026/* 1049/*
1027 * Info interface 1050 * Info interface
@@ -1049,15 +1072,14 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry,
1049 mutex_unlock(&register_mutex); 1072 mutex_unlock(&register_mutex);
1050} 1073}
1051 1074
1052static struct snd_info_entry *snd_pcm_proc_entry = NULL; 1075static struct snd_info_entry *snd_pcm_proc_entry;
1053 1076
1054static void snd_pcm_proc_init(void) 1077static void snd_pcm_proc_init(void)
1055{ 1078{
1056 struct snd_info_entry *entry; 1079 struct snd_info_entry *entry;
1057 1080
1058 if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) { 1081 if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) {
1059 snd_info_set_text_ops(entry, NULL, SNDRV_CARDS * SNDRV_PCM_DEVICES * 128, 1082 snd_info_set_text_ops(entry, NULL, snd_pcm_proc_read);
1060 snd_pcm_proc_read);
1061 if (snd_info_register(entry) < 0) { 1083 if (snd_info_register(entry) < 0) {
1062 snd_info_free_entry(entry); 1084 snd_info_free_entry(entry);
1063 entry = NULL; 1085 entry = NULL;
@@ -1099,33 +1121,3 @@ static void __exit alsa_pcm_exit(void)
1099 1121
1100module_init(alsa_pcm_init) 1122module_init(alsa_pcm_init)
1101module_exit(alsa_pcm_exit) 1123module_exit(alsa_pcm_exit)
1102
1103EXPORT_SYMBOL(snd_pcm_new);
1104EXPORT_SYMBOL(snd_pcm_new_stream);
1105EXPORT_SYMBOL(snd_pcm_notify);
1106EXPORT_SYMBOL(snd_pcm_open_substream);
1107EXPORT_SYMBOL(snd_pcm_release_substream);
1108 /* pcm_native.c */
1109EXPORT_SYMBOL(snd_pcm_link_rwlock);
1110#ifdef CONFIG_PM
1111EXPORT_SYMBOL(snd_pcm_suspend);
1112EXPORT_SYMBOL(snd_pcm_suspend_all);
1113#endif
1114EXPORT_SYMBOL(snd_pcm_kernel_ioctl);
1115EXPORT_SYMBOL(snd_pcm_mmap_data);
1116#if SNDRV_PCM_INFO_MMAP_IOMEM
1117EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
1118#endif
1119 /* pcm_misc.c */
1120EXPORT_SYMBOL(snd_pcm_format_signed);
1121EXPORT_SYMBOL(snd_pcm_format_unsigned);
1122EXPORT_SYMBOL(snd_pcm_format_linear);
1123EXPORT_SYMBOL(snd_pcm_format_little_endian);
1124EXPORT_SYMBOL(snd_pcm_format_big_endian);
1125EXPORT_SYMBOL(snd_pcm_format_width);
1126EXPORT_SYMBOL(snd_pcm_format_physical_width);
1127EXPORT_SYMBOL(snd_pcm_format_size);
1128EXPORT_SYMBOL(snd_pcm_format_silence_64);
1129EXPORT_SYMBOL(snd_pcm_format_set_silence);
1130EXPORT_SYMBOL(snd_pcm_build_linear_format);
1131EXPORT_SYMBOL(snd_pcm_limit_hw_rates);
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index e5133033de5e..2b8aab6fd6cd 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -497,9 +497,9 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
497 case SNDRV_PCM_IOCTL_LINK: 497 case SNDRV_PCM_IOCTL_LINK:
498 case SNDRV_PCM_IOCTL_UNLINK: 498 case SNDRV_PCM_IOCTL_UNLINK:
499 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 499 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
500 return snd_pcm_playback_ioctl1(substream, cmd, argp); 500 return snd_pcm_playback_ioctl1(file, substream, cmd, argp);
501 else 501 else
502 return snd_pcm_capture_ioctl1(substream, cmd, argp); 502 return snd_pcm_capture_ioctl1(file, substream, cmd, argp);
503 case SNDRV_PCM_IOCTL_HW_REFINE32: 503 case SNDRV_PCM_IOCTL_HW_REFINE32:
504 return snd_pcm_ioctl_hw_params_compat(substream, 1, argp); 504 return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
505 case SNDRV_PCM_IOCTL_HW_PARAMS32: 505 case SNDRV_PCM_IOCTL_HW_PARAMS32:
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index eedc6cb038bb..0bb142a28539 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -289,6 +289,7 @@ void snd_pcm_set_ops(struct snd_pcm *pcm, int direction, struct snd_pcm_ops *ops
289 substream->ops = ops; 289 substream->ops = ops;
290} 290}
291 291
292EXPORT_SYMBOL(snd_pcm_set_ops);
292 293
293/** 294/**
294 * snd_pcm_sync - set the PCM sync id 295 * snd_pcm_sync - set the PCM sync id
@@ -306,13 +307,12 @@ void snd_pcm_set_sync(struct snd_pcm_substream *substream)
306 runtime->sync.id32[3] = -1; 307 runtime->sync.id32[3] = -1;
307} 308}
308 309
310EXPORT_SYMBOL(snd_pcm_set_sync);
311
309/* 312/*
310 * Standard ioctl routine 313 * Standard ioctl routine
311 */ 314 */
312 315
313/* Code taken from alsa-lib */
314#define assert(a) snd_assert((a), return -EINVAL)
315
316static inline unsigned int div32(unsigned int a, unsigned int b, 316static inline unsigned int div32(unsigned int a, unsigned int b,
317 unsigned int *r) 317 unsigned int *r)
318{ 318{
@@ -369,56 +369,6 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b,
369 return n; 369 return n;
370} 370}
371 371
372static int snd_interval_refine_min(struct snd_interval *i, unsigned int min, int openmin)
373{
374 int changed = 0;
375 assert(!snd_interval_empty(i));
376 if (i->min < min) {
377 i->min = min;
378 i->openmin = openmin;
379 changed = 1;
380 } else if (i->min == min && !i->openmin && openmin) {
381 i->openmin = 1;
382 changed = 1;
383 }
384 if (i->integer) {
385 if (i->openmin) {
386 i->min++;
387 i->openmin = 0;
388 }
389 }
390 if (snd_interval_checkempty(i)) {
391 snd_interval_none(i);
392 return -EINVAL;
393 }
394 return changed;
395}
396
397static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int openmax)
398{
399 int changed = 0;
400 assert(!snd_interval_empty(i));
401 if (i->max > max) {
402 i->max = max;
403 i->openmax = openmax;
404 changed = 1;
405 } else if (i->max == max && !i->openmax && openmax) {
406 i->openmax = 1;
407 changed = 1;
408 }
409 if (i->integer) {
410 if (i->openmax) {
411 i->max--;
412 i->openmax = 0;
413 }
414 }
415 if (snd_interval_checkempty(i)) {
416 snd_interval_none(i);
417 return -EINVAL;
418 }
419 return changed;
420}
421
422/** 372/**
423 * snd_interval_refine - refine the interval value of configurator 373 * snd_interval_refine - refine the interval value of configurator
424 * @i: the interval value to refine 374 * @i: the interval value to refine
@@ -433,7 +383,7 @@ static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int
433int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) 383int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v)
434{ 384{
435 int changed = 0; 385 int changed = 0;
436 assert(!snd_interval_empty(i)); 386 snd_assert(!snd_interval_empty(i), return -EINVAL);
437 if (i->min < v->min) { 387 if (i->min < v->min) {
438 i->min = v->min; 388 i->min = v->min;
439 i->openmin = v->openmin; 389 i->openmin = v->openmin;
@@ -472,9 +422,11 @@ int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v)
472 return changed; 422 return changed;
473} 423}
474 424
425EXPORT_SYMBOL(snd_interval_refine);
426
475static int snd_interval_refine_first(struct snd_interval *i) 427static int snd_interval_refine_first(struct snd_interval *i)
476{ 428{
477 assert(!snd_interval_empty(i)); 429 snd_assert(!snd_interval_empty(i), return -EINVAL);
478 if (snd_interval_single(i)) 430 if (snd_interval_single(i))
479 return 0; 431 return 0;
480 i->max = i->min; 432 i->max = i->min;
@@ -486,7 +438,7 @@ static int snd_interval_refine_first(struct snd_interval *i)
486 438
487static int snd_interval_refine_last(struct snd_interval *i) 439static int snd_interval_refine_last(struct snd_interval *i)
488{ 440{
489 assert(!snd_interval_empty(i)); 441 snd_assert(!snd_interval_empty(i), return -EINVAL);
490 if (snd_interval_single(i)) 442 if (snd_interval_single(i))
491 return 0; 443 return 0;
492 i->min = i->max; 444 i->min = i->max;
@@ -496,16 +448,6 @@ static int snd_interval_refine_last(struct snd_interval *i)
496 return 1; 448 return 1;
497} 449}
498 450
499static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
500{
501 struct snd_interval t;
502 t.empty = 0;
503 t.min = t.max = val;
504 t.openmin = t.openmax = 0;
505 t.integer = 1;
506 return snd_interval_refine(i, &t);
507}
508
509void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c) 451void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c)
510{ 452{
511 if (a->empty || b->empty) { 453 if (a->empty || b->empty) {
@@ -621,7 +563,6 @@ void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k,
621 c->integer = 0; 563 c->integer = 0;
622} 564}
623 565
624#undef assert
625/* ---- */ 566/* ---- */
626 567
627 568
@@ -727,6 +668,8 @@ int snd_interval_ratnum(struct snd_interval *i,
727 return err; 668 return err;
728} 669}
729 670
671EXPORT_SYMBOL(snd_interval_ratnum);
672
730/** 673/**
731 * snd_interval_ratden - refine the interval value 674 * snd_interval_ratden - refine the interval value
732 * @i: interval to refine 675 * @i: interval to refine
@@ -877,6 +820,8 @@ int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *
877 return changed; 820 return changed;
878} 821}
879 822
823EXPORT_SYMBOL(snd_interval_list);
824
880static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step) 825static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step)
881{ 826{
882 unsigned int n; 827 unsigned int n;
@@ -953,6 +898,8 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
953 return 0; 898 return 0;
954} 899}
955 900
901EXPORT_SYMBOL(snd_pcm_hw_rule_add);
902
956/** 903/**
957 * snd_pcm_hw_constraint_mask 904 * snd_pcm_hw_constraint_mask
958 * @runtime: PCM runtime instance 905 * @runtime: PCM runtime instance
@@ -1007,6 +954,8 @@ int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_pa
1007 return snd_interval_setinteger(constrs_interval(constrs, var)); 954 return snd_interval_setinteger(constrs_interval(constrs, var));
1008} 955}
1009 956
957EXPORT_SYMBOL(snd_pcm_hw_constraint_integer);
958
1010/** 959/**
1011 * snd_pcm_hw_constraint_minmax 960 * snd_pcm_hw_constraint_minmax
1012 * @runtime: PCM runtime instance 961 * @runtime: PCM runtime instance
@@ -1028,6 +977,8 @@ int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_par
1028 return snd_interval_refine(constrs_interval(constrs, var), &t); 977 return snd_interval_refine(constrs_interval(constrs, var), &t);
1029} 978}
1030 979
980EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax);
981
1031static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, 982static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params,
1032 struct snd_pcm_hw_rule *rule) 983 struct snd_pcm_hw_rule *rule)
1033{ 984{
@@ -1055,6 +1006,8 @@ int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
1055 var, -1); 1006 var, -1);
1056} 1007}
1057 1008
1009EXPORT_SYMBOL(snd_pcm_hw_constraint_list);
1010
1058static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, 1011static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params,
1059 struct snd_pcm_hw_rule *rule) 1012 struct snd_pcm_hw_rule *rule)
1060{ 1013{
@@ -1087,6 +1040,8 @@ int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime,
1087 var, -1); 1040 var, -1);
1088} 1041}
1089 1042
1043EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums);
1044
1090static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params, 1045static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params,
1091 struct snd_pcm_hw_rule *rule) 1046 struct snd_pcm_hw_rule *rule)
1092{ 1047{
@@ -1118,6 +1073,8 @@ int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime,
1118 var, -1); 1073 var, -1);
1119} 1074}
1120 1075
1076EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens);
1077
1121static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, 1078static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params,
1122 struct snd_pcm_hw_rule *rule) 1079 struct snd_pcm_hw_rule *rule)
1123{ 1080{
@@ -1149,6 +1106,8 @@ int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime,
1149 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); 1106 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
1150} 1107}
1151 1108
1109EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits);
1110
1152static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params, 1111static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params,
1153 struct snd_pcm_hw_rule *rule) 1112 struct snd_pcm_hw_rule *rule)
1154{ 1113{
@@ -1173,6 +1132,8 @@ int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime,
1173 var, -1); 1132 var, -1);
1174} 1133}
1175 1134
1135EXPORT_SYMBOL(snd_pcm_hw_constraint_step);
1136
1176static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) 1137static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
1177{ 1138{
1178 static int pow2_sizes[] = { 1139 static int pow2_sizes[] = {
@@ -1200,11 +1161,7 @@ int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
1200 var, -1); 1161 var, -1);
1201} 1162}
1202 1163
1203/* To use the same code we have in alsa-lib */ 1164EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2);
1204#define assert(i) snd_assert((i), return -EINVAL)
1205#ifndef INT_MIN
1206#define INT_MIN ((int)((unsigned int)INT_MAX+1))
1207#endif
1208 1165
1209static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params, 1166static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params,
1210 snd_pcm_hw_param_t var) 1167 snd_pcm_hw_param_t var)
@@ -1224,18 +1181,6 @@ static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params,
1224 snd_BUG(); 1181 snd_BUG();
1225} 1182}
1226 1183
1227#if 0
1228/*
1229 * snd_pcm_hw_param_any
1230 */
1231int snd_pcm_hw_param_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1232 snd_pcm_hw_param_t var)
1233{
1234 _snd_pcm_hw_param_any(params, var);
1235 return snd_pcm_hw_refine(pcm, params);
1236}
1237#endif /* 0 */
1238
1239void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params) 1184void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params)
1240{ 1185{
1241 unsigned int k; 1186 unsigned int k;
@@ -1247,18 +1192,7 @@ void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params)
1247 params->info = ~0U; 1192 params->info = ~0U;
1248} 1193}
1249 1194
1250#if 0 1195EXPORT_SYMBOL(_snd_pcm_hw_params_any);
1251/*
1252 * snd_pcm_hw_params_any
1253 *
1254 * Fill PARAMS with full configuration space boundaries
1255 */
1256int snd_pcm_hw_params_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params)
1257{
1258 _snd_pcm_hw_params_any(params);
1259 return snd_pcm_hw_refine(pcm, params);
1260}
1261#endif /* 0 */
1262 1196
1263/** 1197/**
1264 * snd_pcm_hw_param_value 1198 * snd_pcm_hw_param_value
@@ -1269,8 +1203,8 @@ int snd_pcm_hw_params_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_param
1269 * Return the value for field PAR if it's fixed in configuration space 1203 * Return the value for field PAR if it's fixed in configuration space
1270 * defined by PARAMS. Return -EINVAL otherwise 1204 * defined by PARAMS. Return -EINVAL otherwise
1271 */ 1205 */
1272static int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, 1206int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
1273 snd_pcm_hw_param_t var, int *dir) 1207 snd_pcm_hw_param_t var, int *dir)
1274{ 1208{
1275 if (hw_is_mask(var)) { 1209 if (hw_is_mask(var)) {
1276 const struct snd_mask *mask = hw_param_mask_c(params, var); 1210 const struct snd_mask *mask = hw_param_mask_c(params, var);
@@ -1288,61 +1222,10 @@ static int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
1288 *dir = i->openmin; 1222 *dir = i->openmin;
1289 return snd_interval_value(i); 1223 return snd_interval_value(i);
1290 } 1224 }
1291 assert(0);
1292 return -EINVAL;
1293}
1294
1295/**
1296 * snd_pcm_hw_param_value_min
1297 * @params: the hw_params instance
1298 * @var: parameter to retrieve
1299 * @dir: pointer to the direction (-1,0,1) or NULL
1300 *
1301 * Return the minimum value for field PAR.
1302 */
1303unsigned int snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
1304 snd_pcm_hw_param_t var, int *dir)
1305{
1306 if (hw_is_mask(var)) {
1307 if (dir)
1308 *dir = 0;
1309 return snd_mask_min(hw_param_mask_c(params, var));
1310 }
1311 if (hw_is_interval(var)) {
1312 const struct snd_interval *i = hw_param_interval_c(params, var);
1313 if (dir)
1314 *dir = i->openmin;
1315 return snd_interval_min(i);
1316 }
1317 assert(0);
1318 return -EINVAL; 1225 return -EINVAL;
1319} 1226}
1320 1227
1321/** 1228EXPORT_SYMBOL(snd_pcm_hw_param_value);
1322 * snd_pcm_hw_param_value_max
1323 * @params: the hw_params instance
1324 * @var: parameter to retrieve
1325 * @dir: pointer to the direction (-1,0,1) or NULL
1326 *
1327 * Return the maximum value for field PAR.
1328 */
1329unsigned int snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
1330 snd_pcm_hw_param_t var, int *dir)
1331{
1332 if (hw_is_mask(var)) {
1333 if (dir)
1334 *dir = 0;
1335 return snd_mask_max(hw_param_mask_c(params, var));
1336 }
1337 if (hw_is_interval(var)) {
1338 const struct snd_interval *i = hw_param_interval_c(params, var);
1339 if (dir)
1340 *dir = - (int) i->openmax;
1341 return snd_interval_max(i);
1342 }
1343 assert(0);
1344 return -EINVAL;
1345}
1346 1229
1347void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, 1230void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params,
1348 snd_pcm_hw_param_t var) 1231 snd_pcm_hw_param_t var)
@@ -1360,42 +1243,7 @@ void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params,
1360 } 1243 }
1361} 1244}
1362 1245
1363int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params, 1246EXPORT_SYMBOL(_snd_pcm_hw_param_setempty);
1364 snd_pcm_hw_param_t var)
1365{
1366 int changed;
1367 assert(hw_is_interval(var));
1368 changed = snd_interval_setinteger(hw_param_interval(params, var));
1369 if (changed) {
1370 params->cmask |= 1 << var;
1371 params->rmask |= 1 << var;
1372 }
1373 return changed;
1374}
1375
1376#if 0
1377/*
1378 * snd_pcm_hw_param_setinteger
1379 *
1380 * Inside configuration space defined by PARAMS remove from PAR all
1381 * non integer values. Reduce configuration space accordingly.
1382 * Return -EINVAL if the configuration space is empty
1383 */
1384int snd_pcm_hw_param_setinteger(struct snd_pcm_substream *pcm,
1385 struct snd_pcm_hw_params *params,
1386 snd_pcm_hw_param_t var)
1387{
1388 int changed = _snd_pcm_hw_param_setinteger(params, var);
1389 if (changed < 0)
1390 return changed;
1391 if (params->rmask) {
1392 int err = snd_pcm_hw_refine(pcm, params);
1393 if (err < 0)
1394 return err;
1395 }
1396 return 0;
1397}
1398#endif /* 0 */
1399 1247
1400static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, 1248static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
1401 snd_pcm_hw_param_t var) 1249 snd_pcm_hw_param_t var)
@@ -1405,10 +1253,8 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
1405 changed = snd_mask_refine_first(hw_param_mask(params, var)); 1253 changed = snd_mask_refine_first(hw_param_mask(params, var));
1406 else if (hw_is_interval(var)) 1254 else if (hw_is_interval(var))
1407 changed = snd_interval_refine_first(hw_param_interval(params, var)); 1255 changed = snd_interval_refine_first(hw_param_interval(params, var));
1408 else { 1256 else
1409 assert(0);
1410 return -EINVAL; 1257 return -EINVAL;
1411 }
1412 if (changed) { 1258 if (changed) {
1413 params->cmask |= 1 << var; 1259 params->cmask |= 1 << var;
1414 params->rmask |= 1 << var; 1260 params->rmask |= 1 << var;
@@ -1428,20 +1274,22 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
1428 * values > minimum. Reduce configuration space accordingly. 1274 * values > minimum. Reduce configuration space accordingly.
1429 * Return the minimum. 1275 * Return the minimum.
1430 */ 1276 */
1431static int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, 1277int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm,
1432 struct snd_pcm_hw_params *params, 1278 struct snd_pcm_hw_params *params,
1433 snd_pcm_hw_param_t var, int *dir) 1279 snd_pcm_hw_param_t var, int *dir)
1434{ 1280{
1435 int changed = _snd_pcm_hw_param_first(params, var); 1281 int changed = _snd_pcm_hw_param_first(params, var);
1436 if (changed < 0) 1282 if (changed < 0)
1437 return changed; 1283 return changed;
1438 if (params->rmask) { 1284 if (params->rmask) {
1439 int err = snd_pcm_hw_refine(pcm, params); 1285 int err = snd_pcm_hw_refine(pcm, params);
1440 assert(err >= 0); 1286 snd_assert(err >= 0, return err);
1441 } 1287 }
1442 return snd_pcm_hw_param_value(params, var, dir); 1288 return snd_pcm_hw_param_value(params, var, dir);
1443} 1289}
1444 1290
1291EXPORT_SYMBOL(snd_pcm_hw_param_first);
1292
1445static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, 1293static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
1446 snd_pcm_hw_param_t var) 1294 snd_pcm_hw_param_t var)
1447{ 1295{
@@ -1450,10 +1298,8 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
1450 changed = snd_mask_refine_last(hw_param_mask(params, var)); 1298 changed = snd_mask_refine_last(hw_param_mask(params, var));
1451 else if (hw_is_interval(var)) 1299 else if (hw_is_interval(var))
1452 changed = snd_interval_refine_last(hw_param_interval(params, var)); 1300 changed = snd_interval_refine_last(hw_param_interval(params, var));
1453 else { 1301 else
1454 assert(0);
1455 return -EINVAL; 1302 return -EINVAL;
1456 }
1457 if (changed) { 1303 if (changed) {
1458 params->cmask |= 1 << var; 1304 params->cmask |= 1 << var;
1459 params->rmask |= 1 << var; 1305 params->rmask |= 1 << var;
@@ -1473,381 +1319,21 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
1473 * values < maximum. Reduce configuration space accordingly. 1319 * values < maximum. Reduce configuration space accordingly.
1474 * Return the maximum. 1320 * Return the maximum.
1475 */ 1321 */
1476static int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, 1322int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
1477 struct snd_pcm_hw_params *params, 1323 struct snd_pcm_hw_params *params,
1478 snd_pcm_hw_param_t var, int *dir) 1324 snd_pcm_hw_param_t var, int *dir)
1479{ 1325{
1480 int changed = _snd_pcm_hw_param_last(params, var); 1326 int changed = _snd_pcm_hw_param_last(params, var);
1481 if (changed < 0) 1327 if (changed < 0)
1482 return changed; 1328 return changed;
1483 if (params->rmask) { 1329 if (params->rmask) {
1484 int err = snd_pcm_hw_refine(pcm, params); 1330 int err = snd_pcm_hw_refine(pcm, params);
1485 assert(err >= 0); 1331 snd_assert(err >= 0, return err);
1486 } 1332 }
1487 return snd_pcm_hw_param_value(params, var, dir); 1333 return snd_pcm_hw_param_value(params, var, dir);
1488} 1334}
1489 1335
1490int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, 1336EXPORT_SYMBOL(snd_pcm_hw_param_last);
1491 snd_pcm_hw_param_t var, unsigned int val, int dir)
1492{
1493 int changed;
1494 int open = 0;
1495 if (dir) {
1496 if (dir > 0) {
1497 open = 1;
1498 } else if (dir < 0) {
1499 if (val > 0) {
1500 open = 1;
1501 val--;
1502 }
1503 }
1504 }
1505 if (hw_is_mask(var))
1506 changed = snd_mask_refine_min(hw_param_mask(params, var), val + !!open);
1507 else if (hw_is_interval(var))
1508 changed = snd_interval_refine_min(hw_param_interval(params, var), val, open);
1509 else {
1510 assert(0);
1511 return -EINVAL;
1512 }
1513 if (changed) {
1514 params->cmask |= 1 << var;
1515 params->rmask |= 1 << var;
1516 }
1517 return changed;
1518}
1519
1520/**
1521 * snd_pcm_hw_param_min
1522 * @pcm: PCM instance
1523 * @params: the hw_params instance
1524 * @var: parameter to retrieve
1525 * @val: minimal value
1526 * @dir: pointer to the direction (-1,0,1) or NULL
1527 *
1528 * Inside configuration space defined by PARAMS remove from PAR all
1529 * values < VAL. Reduce configuration space accordingly.
1530 * Return new minimum or -EINVAL if the configuration space is empty
1531 */
1532static int snd_pcm_hw_param_min(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1533 snd_pcm_hw_param_t var, unsigned int val,
1534 int *dir)
1535{
1536 int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0);
1537 if (changed < 0)
1538 return changed;
1539 if (params->rmask) {
1540 int err = snd_pcm_hw_refine(pcm, params);
1541 if (err < 0)
1542 return err;
1543 }
1544 return snd_pcm_hw_param_value_min(params, var, dir);
1545}
1546
1547static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params,
1548 snd_pcm_hw_param_t var, unsigned int val,
1549 int dir)
1550{
1551 int changed;
1552 int open = 0;
1553 if (dir) {
1554 if (dir < 0) {
1555 open = 1;
1556 } else if (dir > 0) {
1557 open = 1;
1558 val++;
1559 }
1560 }
1561 if (hw_is_mask(var)) {
1562 if (val == 0 && open) {
1563 snd_mask_none(hw_param_mask(params, var));
1564 changed = -EINVAL;
1565 } else
1566 changed = snd_mask_refine_max(hw_param_mask(params, var), val - !!open);
1567 } else if (hw_is_interval(var))
1568 changed = snd_interval_refine_max(hw_param_interval(params, var), val, open);
1569 else {
1570 assert(0);
1571 return -EINVAL;
1572 }
1573 if (changed) {
1574 params->cmask |= 1 << var;
1575 params->rmask |= 1 << var;
1576 }
1577 return changed;
1578}
1579
1580/**
1581 * snd_pcm_hw_param_max
1582 * @pcm: PCM instance
1583 * @params: the hw_params instance
1584 * @var: parameter to retrieve
1585 * @val: maximal value
1586 * @dir: pointer to the direction (-1,0,1) or NULL
1587 *
1588 * Inside configuration space defined by PARAMS remove from PAR all
1589 * values >= VAL + 1. Reduce configuration space accordingly.
1590 * Return new maximum or -EINVAL if the configuration space is empty
1591 */
1592static int snd_pcm_hw_param_max(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1593 snd_pcm_hw_param_t var, unsigned int val,
1594 int *dir)
1595{
1596 int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0);
1597 if (changed < 0)
1598 return changed;
1599 if (params->rmask) {
1600 int err = snd_pcm_hw_refine(pcm, params);
1601 if (err < 0)
1602 return err;
1603 }
1604 return snd_pcm_hw_param_value_max(params, var, dir);
1605}
1606
1607int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
1608 snd_pcm_hw_param_t var, unsigned int val, int dir)
1609{
1610 int changed;
1611 if (hw_is_mask(var)) {
1612 struct snd_mask *m = hw_param_mask(params, var);
1613 if (val == 0 && dir < 0) {
1614 changed = -EINVAL;
1615 snd_mask_none(m);
1616 } else {
1617 if (dir > 0)
1618 val++;
1619 else if (dir < 0)
1620 val--;
1621 changed = snd_mask_refine_set(hw_param_mask(params, var), val);
1622 }
1623 } else if (hw_is_interval(var)) {
1624 struct snd_interval *i = hw_param_interval(params, var);
1625 if (val == 0 && dir < 0) {
1626 changed = -EINVAL;
1627 snd_interval_none(i);
1628 } else if (dir == 0)
1629 changed = snd_interval_refine_set(i, val);
1630 else {
1631 struct snd_interval t;
1632 t.openmin = 1;
1633 t.openmax = 1;
1634 t.empty = 0;
1635 t.integer = 0;
1636 if (dir < 0) {
1637 t.min = val - 1;
1638 t.max = val;
1639 } else {
1640 t.min = val;
1641 t.max = val+1;
1642 }
1643 changed = snd_interval_refine(i, &t);
1644 }
1645 } else {
1646 assert(0);
1647 return -EINVAL;
1648 }
1649 if (changed) {
1650 params->cmask |= 1 << var;
1651 params->rmask |= 1 << var;
1652 }
1653 return changed;
1654}
1655
1656/**
1657 * snd_pcm_hw_param_set
1658 * @pcm: PCM instance
1659 * @params: the hw_params instance
1660 * @var: parameter to retrieve
1661 * @val: value to set
1662 * @dir: pointer to the direction (-1,0,1) or NULL
1663 *
1664 * Inside configuration space defined by PARAMS remove from PAR all
1665 * values != VAL. Reduce configuration space accordingly.
1666 * Return VAL or -EINVAL if the configuration space is empty
1667 */
1668int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1669 snd_pcm_hw_param_t var, unsigned int val, int dir)
1670{
1671 int changed = _snd_pcm_hw_param_set(params, var, val, dir);
1672 if (changed < 0)
1673 return changed;
1674 if (params->rmask) {
1675 int err = snd_pcm_hw_refine(pcm, params);
1676 if (err < 0)
1677 return err;
1678 }
1679 return snd_pcm_hw_param_value(params, var, NULL);
1680}
1681
1682static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params,
1683 snd_pcm_hw_param_t var, const struct snd_mask *val)
1684{
1685 int changed;
1686 assert(hw_is_mask(var));
1687 changed = snd_mask_refine(hw_param_mask(params, var), val);
1688 if (changed) {
1689 params->cmask |= 1 << var;
1690 params->rmask |= 1 << var;
1691 }
1692 return changed;
1693}
1694
1695/**
1696 * snd_pcm_hw_param_mask
1697 * @pcm: PCM instance
1698 * @params: the hw_params instance
1699 * @var: parameter to retrieve
1700 * @val: mask to apply
1701 *
1702 * Inside configuration space defined by PARAMS remove from PAR all values
1703 * not contained in MASK. Reduce configuration space accordingly.
1704 * This function can be called only for SNDRV_PCM_HW_PARAM_ACCESS,
1705 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
1706 * Return 0 on success or -EINVAL
1707 * if the configuration space is empty
1708 */
1709int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1710 snd_pcm_hw_param_t var, const struct snd_mask *val)
1711{
1712 int changed = _snd_pcm_hw_param_mask(params, var, val);
1713 if (changed < 0)
1714 return changed;
1715 if (params->rmask) {
1716 int err = snd_pcm_hw_refine(pcm, params);
1717 if (err < 0)
1718 return err;
1719 }
1720 return 0;
1721}
1722
1723static int boundary_sub(int a, int adir,
1724 int b, int bdir,
1725 int *c, int *cdir)
1726{
1727 adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0);
1728 bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0);
1729 *c = a - b;
1730 *cdir = adir - bdir;
1731 if (*cdir == -2) {
1732 assert(*c > INT_MIN);
1733 (*c)--;
1734 } else if (*cdir == 2) {
1735 assert(*c < INT_MAX);
1736 (*c)++;
1737 }
1738 return 0;
1739}
1740
1741static int boundary_lt(unsigned int a, int adir,
1742 unsigned int b, int bdir)
1743{
1744 assert(a > 0 || adir >= 0);
1745 assert(b > 0 || bdir >= 0);
1746 if (adir < 0) {
1747 a--;
1748 adir = 1;
1749 } else if (adir > 0)
1750 adir = 1;
1751 if (bdir < 0) {
1752 b--;
1753 bdir = 1;
1754 } else if (bdir > 0)
1755 bdir = 1;
1756 return a < b || (a == b && adir < bdir);
1757}
1758
1759/* Return 1 if min is nearer to best than max */
1760static int boundary_nearer(int min, int mindir,
1761 int best, int bestdir,
1762 int max, int maxdir)
1763{
1764 int dmin, dmindir;
1765 int dmax, dmaxdir;
1766 boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir);
1767 boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir);
1768 return boundary_lt(dmin, dmindir, dmax, dmaxdir);
1769}
1770
1771/**
1772 * snd_pcm_hw_param_near
1773 * @pcm: PCM instance
1774 * @params: the hw_params instance
1775 * @var: parameter to retrieve
1776 * @best: value to set
1777 * @dir: pointer to the direction (-1,0,1) or NULL
1778 *
1779 * Inside configuration space defined by PARAMS set PAR to the available value
1780 * nearest to VAL. Reduce configuration space accordingly.
1781 * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS,
1782 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
1783 * Return the value found.
1784 */
1785int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1786 snd_pcm_hw_param_t var, unsigned int best, int *dir)
1787{
1788 struct snd_pcm_hw_params *save = NULL;
1789 int v;
1790 unsigned int saved_min;
1791 int last = 0;
1792 int min, max;
1793 int mindir, maxdir;
1794 int valdir = dir ? *dir : 0;
1795 /* FIXME */
1796 if (best > INT_MAX)
1797 best = INT_MAX;
1798 min = max = best;
1799 mindir = maxdir = valdir;
1800 if (maxdir > 0)
1801 maxdir = 0;
1802 else if (maxdir == 0)
1803 maxdir = -1;
1804 else {
1805 maxdir = 1;
1806 max--;
1807 }
1808 save = kmalloc(sizeof(*save), GFP_KERNEL);
1809 if (save == NULL)
1810 return -ENOMEM;
1811 *save = *params;
1812 saved_min = min;
1813 min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
1814 if (min >= 0) {
1815 struct snd_pcm_hw_params *params1;
1816 if (max < 0)
1817 goto _end;
1818 if ((unsigned int)min == saved_min && mindir == valdir)
1819 goto _end;
1820 params1 = kmalloc(sizeof(*params1), GFP_KERNEL);
1821 if (params1 == NULL) {
1822 kfree(save);
1823 return -ENOMEM;
1824 }
1825 *params1 = *save;
1826 max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir);
1827 if (max < 0) {
1828 kfree(params1);
1829 goto _end;
1830 }
1831 if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) {
1832 *params = *params1;
1833 last = 1;
1834 }
1835 kfree(params1);
1836 } else {
1837 *params = *save;
1838 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
1839 assert(max >= 0);
1840 last = 1;
1841 }
1842 _end:
1843 kfree(save);
1844 if (last)
1845 v = snd_pcm_hw_param_last(pcm, params, var, dir);
1846 else
1847 v = snd_pcm_hw_param_first(pcm, params, var, dir);
1848 assert(v >= 0);
1849 return v;
1850}
1851 1337
1852/** 1338/**
1853 * snd_pcm_hw_param_choose 1339 * snd_pcm_hw_param_choose
@@ -1859,39 +1345,32 @@ int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, struct snd_pcm_hw_param
1859 * first access, first format, first subformat, min channels, 1345 * first access, first format, first subformat, min channels,
1860 * min rate, min period time, max buffer size, min tick time 1346 * min rate, min period time, max buffer size, min tick time
1861 */ 1347 */
1862int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params) 1348int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm,
1863{ 1349 struct snd_pcm_hw_params *params)
1864 int err; 1350{
1865 1351 static int vars[] = {
1866 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_ACCESS, NULL); 1352 SNDRV_PCM_HW_PARAM_ACCESS,
1867 assert(err >= 0); 1353 SNDRV_PCM_HW_PARAM_FORMAT,
1868 1354 SNDRV_PCM_HW_PARAM_SUBFORMAT,
1869 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_FORMAT, NULL); 1355 SNDRV_PCM_HW_PARAM_CHANNELS,
1870 assert(err >= 0); 1356 SNDRV_PCM_HW_PARAM_RATE,
1871 1357 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1872 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_SUBFORMAT, NULL); 1358 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
1873 assert(err >= 0); 1359 SNDRV_PCM_HW_PARAM_TICK_TIME,
1874 1360 -1
1875 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_CHANNELS, NULL); 1361 };
1876 assert(err >= 0); 1362 int err, *v;
1877
1878 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_RATE, NULL);
1879 assert(err >= 0);
1880
1881 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_PERIOD_TIME, NULL);
1882 assert(err >= 0);
1883
1884 err = snd_pcm_hw_param_last(pcm, params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL);
1885 assert(err >= 0);
1886
1887 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_TICK_TIME, NULL);
1888 assert(err >= 0);
1889 1363
1364 for (v = vars; *v != -1; v++) {
1365 if (*v != SNDRV_PCM_HW_PARAM_BUFFER_SIZE)
1366 err = snd_pcm_hw_param_first(pcm, params, *v, NULL);
1367 else
1368 err = snd_pcm_hw_param_last(pcm, params, *v, NULL);
1369 snd_assert(err >= 0, return err);
1370 }
1890 return 0; 1371 return 0;
1891} 1372}
1892 1373
1893#undef assert
1894
1895static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream, 1374static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
1896 void *arg) 1375 void *arg)
1897{ 1376{
@@ -1967,6 +1446,8 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
1967 return -ENXIO; 1446 return -ENXIO;
1968} 1447}
1969 1448
1449EXPORT_SYMBOL(snd_pcm_lib_ioctl);
1450
1970/* 1451/*
1971 * Conditions 1452 * Conditions
1972 */ 1453 */
@@ -2101,6 +1582,8 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
2101 kill_fasync(&runtime->fasync, SIGIO, POLL_IN); 1582 kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
2102} 1583}
2103 1584
1585EXPORT_SYMBOL(snd_pcm_period_elapsed);
1586
2104static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, 1587static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
2105 unsigned int hwoff, 1588 unsigned int hwoff,
2106 unsigned long data, unsigned int off, 1589 unsigned long data, unsigned int off,
@@ -2299,7 +1782,7 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v
2299 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1782 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2300 return -EBADFD; 1783 return -EBADFD;
2301 1784
2302 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 1785 nonblock = !!(substream->f_flags & O_NONBLOCK);
2303 1786
2304 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && 1787 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
2305 runtime->channels > 1) 1788 runtime->channels > 1)
@@ -2308,6 +1791,8 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v
2308 snd_pcm_lib_write_transfer); 1791 snd_pcm_lib_write_transfer);
2309} 1792}
2310 1793
1794EXPORT_SYMBOL(snd_pcm_lib_write);
1795
2311static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, 1796static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
2312 unsigned int hwoff, 1797 unsigned int hwoff,
2313 unsigned long data, unsigned int off, 1798 unsigned long data, unsigned int off,
@@ -2362,7 +1847,7 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
2362 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1847 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2363 return -EBADFD; 1848 return -EBADFD;
2364 1849
2365 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 1850 nonblock = !!(substream->f_flags & O_NONBLOCK);
2366 1851
2367 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 1852 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
2368 return -EINVAL; 1853 return -EINVAL;
@@ -2370,6 +1855,8 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
2370 nonblock, snd_pcm_lib_writev_transfer); 1855 nonblock, snd_pcm_lib_writev_transfer);
2371} 1856}
2372 1857
1858EXPORT_SYMBOL(snd_pcm_lib_writev);
1859
2373static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, 1860static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream,
2374 unsigned int hwoff, 1861 unsigned int hwoff,
2375 unsigned long data, unsigned int off, 1862 unsigned long data, unsigned int off,
@@ -2572,12 +2059,14 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u
2572 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2059 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2573 return -EBADFD; 2060 return -EBADFD;
2574 2061
2575 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2062 nonblock = !!(substream->f_flags & O_NONBLOCK);
2576 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) 2063 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED)
2577 return -EINVAL; 2064 return -EINVAL;
2578 return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); 2065 return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer);
2579} 2066}
2580 2067
2068EXPORT_SYMBOL(snd_pcm_lib_read);
2069
2581static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, 2070static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
2582 unsigned int hwoff, 2071 unsigned int hwoff,
2583 unsigned long data, unsigned int off, 2072 unsigned long data, unsigned int off,
@@ -2629,58 +2118,10 @@ snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
2629 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2118 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2630 return -EBADFD; 2119 return -EBADFD;
2631 2120
2632 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2121 nonblock = !!(substream->f_flags & O_NONBLOCK);
2633 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 2122 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
2634 return -EINVAL; 2123 return -EINVAL;
2635 return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer); 2124 return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer);
2636} 2125}
2637 2126
2638/*
2639 * Exported symbols
2640 */
2641
2642EXPORT_SYMBOL(snd_interval_refine);
2643EXPORT_SYMBOL(snd_interval_list);
2644EXPORT_SYMBOL(snd_interval_ratnum);
2645EXPORT_SYMBOL(_snd_pcm_hw_params_any);
2646EXPORT_SYMBOL(_snd_pcm_hw_param_min);
2647EXPORT_SYMBOL(_snd_pcm_hw_param_set);
2648EXPORT_SYMBOL(_snd_pcm_hw_param_setempty);
2649EXPORT_SYMBOL(_snd_pcm_hw_param_setinteger);
2650EXPORT_SYMBOL(snd_pcm_hw_param_value_min);
2651EXPORT_SYMBOL(snd_pcm_hw_param_value_max);
2652EXPORT_SYMBOL(snd_pcm_hw_param_mask);
2653EXPORT_SYMBOL(snd_pcm_hw_param_first);
2654EXPORT_SYMBOL(snd_pcm_hw_param_last);
2655EXPORT_SYMBOL(snd_pcm_hw_param_near);
2656EXPORT_SYMBOL(snd_pcm_hw_param_set);
2657EXPORT_SYMBOL(snd_pcm_hw_refine);
2658EXPORT_SYMBOL(snd_pcm_hw_constraints_init);
2659EXPORT_SYMBOL(snd_pcm_hw_constraints_complete);
2660EXPORT_SYMBOL(snd_pcm_hw_constraint_list);
2661EXPORT_SYMBOL(snd_pcm_hw_constraint_step);
2662EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums);
2663EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens);
2664EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits);
2665EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax);
2666EXPORT_SYMBOL(snd_pcm_hw_constraint_integer);
2667EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2);
2668EXPORT_SYMBOL(snd_pcm_hw_rule_add);
2669EXPORT_SYMBOL(snd_pcm_set_ops);
2670EXPORT_SYMBOL(snd_pcm_set_sync);
2671EXPORT_SYMBOL(snd_pcm_lib_ioctl);
2672EXPORT_SYMBOL(snd_pcm_stop);
2673EXPORT_SYMBOL(snd_pcm_period_elapsed);
2674EXPORT_SYMBOL(snd_pcm_lib_write);
2675EXPORT_SYMBOL(snd_pcm_lib_read);
2676EXPORT_SYMBOL(snd_pcm_lib_writev);
2677EXPORT_SYMBOL(snd_pcm_lib_readv); 2127EXPORT_SYMBOL(snd_pcm_lib_readv);
2678EXPORT_SYMBOL(snd_pcm_lib_buffer_bytes);
2679EXPORT_SYMBOL(snd_pcm_lib_period_bytes);
2680/* pcm_memory.c */
2681EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all);
2682EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages);
2683EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
2684EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
2685EXPORT_SYMBOL(snd_pcm_lib_malloc_pages);
2686EXPORT_SYMBOL(snd_pcm_lib_free_pages);
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index 428f8c169ee1..067d2056db9a 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -126,6 +126,8 @@ int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm)
126 return 0; 126 return 0;
127} 127}
128 128
129EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all);
130
129#ifdef CONFIG_SND_VERBOSE_PROCFS 131#ifdef CONFIG_SND_VERBOSE_PROCFS
130/* 132/*
131 * read callback for prealloc proc file 133 * read callback for prealloc proc file
@@ -191,9 +193,7 @@ static inline void preallocate_info_init(struct snd_pcm_substream *substream)
191 struct snd_info_entry *entry; 193 struct snd_info_entry *entry;
192 194
193 if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) { 195 if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) {
194 entry->c.text.read_size = 64;
195 entry->c.text.read = snd_pcm_lib_preallocate_proc_read; 196 entry->c.text.read = snd_pcm_lib_preallocate_proc_read;
196 entry->c.text.write_size = 64;
197 entry->c.text.write = snd_pcm_lib_preallocate_proc_write; 197 entry->c.text.write = snd_pcm_lib_preallocate_proc_write;
198 entry->mode |= S_IWUSR; 198 entry->mode |= S_IWUSR;
199 entry->private_data = substream; 199 entry->private_data = substream;
@@ -253,6 +253,8 @@ int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream,
253 return snd_pcm_lib_preallocate_pages1(substream, size, max); 253 return snd_pcm_lib_preallocate_pages1(substream, size, max);
254} 254}
255 255
256EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages);
257
256/** 258/**
257 * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams) 259 * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams)
258 * @pcm: the pcm instance 260 * @pcm: the pcm instance
@@ -280,6 +282,8 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
280 return 0; 282 return 0;
281} 283}
282 284
285EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
286
283/** 287/**
284 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset 288 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset
285 * @substream: the pcm substream instance 289 * @substream: the pcm substream instance
@@ -298,6 +302,8 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne
298 return sgbuf->page_table[idx]; 302 return sgbuf->page_table[idx];
299} 303}
300 304
305EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
306
301/** 307/**
302 * snd_pcm_lib_malloc_pages - allocate the DMA buffer 308 * snd_pcm_lib_malloc_pages - allocate the DMA buffer
303 * @substream: the substream to allocate the DMA buffer to 309 * @substream: the substream to allocate the DMA buffer to
@@ -349,6 +355,8 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size)
349 return 1; /* area was changed */ 355 return 1; /* area was changed */
350} 356}
351 357
358EXPORT_SYMBOL(snd_pcm_lib_malloc_pages);
359
352/** 360/**
353 * snd_pcm_lib_free_pages - release the allocated DMA buffer. 361 * snd_pcm_lib_free_pages - release the allocated DMA buffer.
354 * @substream: the substream to release the DMA buffer 362 * @substream: the substream to release the DMA buffer
@@ -374,3 +382,5 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
374 snd_pcm_set_runtime_buffer(substream, NULL); 382 snd_pcm_set_runtime_buffer(substream, NULL);
375 return 0; 383 return 0;
376} 384}
385
386EXPORT_SYMBOL(snd_pcm_lib_free_pages);
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index 593c77f4d181..0019c59a779d 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -207,6 +207,8 @@ int snd_pcm_format_signed(snd_pcm_format_t format)
207 return val; 207 return val;
208} 208}
209 209
210EXPORT_SYMBOL(snd_pcm_format_signed);
211
210/** 212/**
211 * snd_pcm_format_unsigned - Check the PCM format is unsigned linear 213 * snd_pcm_format_unsigned - Check the PCM format is unsigned linear
212 * @format: the format to check 214 * @format: the format to check
@@ -224,6 +226,8 @@ int snd_pcm_format_unsigned(snd_pcm_format_t format)
224 return !val; 226 return !val;
225} 227}
226 228
229EXPORT_SYMBOL(snd_pcm_format_unsigned);
230
227/** 231/**
228 * snd_pcm_format_linear - Check the PCM format is linear 232 * snd_pcm_format_linear - Check the PCM format is linear
229 * @format: the format to check 233 * @format: the format to check
@@ -235,6 +239,8 @@ int snd_pcm_format_linear(snd_pcm_format_t format)
235 return snd_pcm_format_signed(format) >= 0; 239 return snd_pcm_format_signed(format) >= 0;
236} 240}
237 241
242EXPORT_SYMBOL(snd_pcm_format_linear);
243
238/** 244/**
239 * snd_pcm_format_little_endian - Check the PCM format is little-endian 245 * snd_pcm_format_little_endian - Check the PCM format is little-endian
240 * @format: the format to check 246 * @format: the format to check
@@ -252,6 +258,8 @@ int snd_pcm_format_little_endian(snd_pcm_format_t format)
252 return val; 258 return val;
253} 259}
254 260
261EXPORT_SYMBOL(snd_pcm_format_little_endian);
262
255/** 263/**
256 * snd_pcm_format_big_endian - Check the PCM format is big-endian 264 * snd_pcm_format_big_endian - Check the PCM format is big-endian
257 * @format: the format to check 265 * @format: the format to check
@@ -269,6 +277,8 @@ int snd_pcm_format_big_endian(snd_pcm_format_t format)
269 return !val; 277 return !val;
270} 278}
271 279
280EXPORT_SYMBOL(snd_pcm_format_big_endian);
281
272/** 282/**
273 * snd_pcm_format_width - return the bit-width of the format 283 * snd_pcm_format_width - return the bit-width of the format
274 * @format: the format to check 284 * @format: the format to check
@@ -286,6 +296,8 @@ int snd_pcm_format_width(snd_pcm_format_t format)
286 return val; 296 return val;
287} 297}
288 298
299EXPORT_SYMBOL(snd_pcm_format_width);
300
289/** 301/**
290 * snd_pcm_format_physical_width - return the physical bit-width of the format 302 * snd_pcm_format_physical_width - return the physical bit-width of the format
291 * @format: the format to check 303 * @format: the format to check
@@ -303,6 +315,8 @@ int snd_pcm_format_physical_width(snd_pcm_format_t format)
303 return val; 315 return val;
304} 316}
305 317
318EXPORT_SYMBOL(snd_pcm_format_physical_width);
319
306/** 320/**
307 * snd_pcm_format_size - return the byte size of samples on the given format 321 * snd_pcm_format_size - return the byte size of samples on the given format
308 * @format: the format to check 322 * @format: the format to check
@@ -318,6 +332,8 @@ ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
318 return samples * phys_width / 8; 332 return samples * phys_width / 8;
319} 333}
320 334
335EXPORT_SYMBOL(snd_pcm_format_size);
336
321/** 337/**
322 * snd_pcm_format_silence_64 - return the silent data in 8 bytes array 338 * snd_pcm_format_silence_64 - return the silent data in 8 bytes array
323 * @format: the format to check 339 * @format: the format to check
@@ -333,6 +349,8 @@ const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format)
333 return pcm_formats[format].silence; 349 return pcm_formats[format].silence;
334} 350}
335 351
352EXPORT_SYMBOL(snd_pcm_format_silence_64);
353
336/** 354/**
337 * snd_pcm_format_set_silence - set the silence data on the buffer 355 * snd_pcm_format_set_silence - set the silence data on the buffer
338 * @format: the PCM format 356 * @format: the PCM format
@@ -402,6 +420,8 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
402 return 0; 420 return 0;
403} 421}
404 422
423EXPORT_SYMBOL(snd_pcm_format_set_silence);
424
405/* [width][unsigned][bigendian] */ 425/* [width][unsigned][bigendian] */
406static int linear_formats[4][2][2] = { 426static int linear_formats[4][2][2] = {
407 {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8}, 427 {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8},
@@ -432,6 +452,8 @@ snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_end
432 return linear_formats[width][!!unsignd][!!big_endian]; 452 return linear_formats[width][!!unsignd][!!big_endian];
433} 453}
434 454
455EXPORT_SYMBOL(snd_pcm_build_linear_format);
456
435/** 457/**
436 * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields 458 * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields
437 * @runtime: the runtime instance 459 * @runtime: the runtime instance
@@ -463,3 +485,5 @@ int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime)
463 } 485 }
464 return 0; 486 return 0;
465} 487}
488
489EXPORT_SYMBOL(snd_pcm_limit_hw_rates);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 0860c5a84502..439f047929e1 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -71,8 +71,9 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream);
71 */ 71 */
72 72
73DEFINE_RWLOCK(snd_pcm_link_rwlock); 73DEFINE_RWLOCK(snd_pcm_link_rwlock);
74static DECLARE_RWSEM(snd_pcm_link_rwsem); 74EXPORT_SYMBOL(snd_pcm_link_rwlock);
75 75
76static DECLARE_RWSEM(snd_pcm_link_rwsem);
76 77
77static inline mm_segment_t snd_enter_user(void) 78static inline mm_segment_t snd_enter_user(void)
78{ 79{
@@ -319,6 +320,8 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
319 return 0; 320 return 0;
320} 321}
321 322
323EXPORT_SYMBOL(snd_pcm_hw_refine);
324
322static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream, 325static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream,
323 struct snd_pcm_hw_params __user * _params) 326 struct snd_pcm_hw_params __user * _params)
324{ 327{
@@ -369,7 +372,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
369#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 372#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
370 if (!substream->oss.oss) 373 if (!substream->oss.oss)
371#endif 374#endif
372 if (atomic_read(&runtime->mmap_count)) 375 if (atomic_read(&substream->mmap_count))
373 return -EBADFD; 376 return -EBADFD;
374 377
375 params->rmask = ~0U; 378 params->rmask = ~0U;
@@ -482,7 +485,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
482 return -EBADFD; 485 return -EBADFD;
483 } 486 }
484 snd_pcm_stream_unlock_irq(substream); 487 snd_pcm_stream_unlock_irq(substream);
485 if (atomic_read(&runtime->mmap_count)) 488 if (atomic_read(&substream->mmap_count))
486 return -EBADFD; 489 return -EBADFD;
487 if (substream->ops->hw_free) 490 if (substream->ops->hw_free)
488 result = substream->ops->hw_free(substream); 491 result = substream->ops->hw_free(substream);
@@ -936,6 +939,8 @@ int snd_pcm_stop(struct snd_pcm_substream *substream, int state)
936 return snd_pcm_action(&snd_pcm_action_stop, substream, state); 939 return snd_pcm_action(&snd_pcm_action_stop, substream, state);
937} 940}
938 941
942EXPORT_SYMBOL(snd_pcm_stop);
943
939/** 944/**
940 * snd_pcm_drain_done 945 * snd_pcm_drain_done
941 * @substream: the PCM substream 946 * @substream: the PCM substream
@@ -1085,6 +1090,8 @@ int snd_pcm_suspend(struct snd_pcm_substream *substream)
1085 return err; 1090 return err;
1086} 1091}
1087 1092
1093EXPORT_SYMBOL(snd_pcm_suspend);
1094
1088/** 1095/**
1089 * snd_pcm_suspend_all 1096 * snd_pcm_suspend_all
1090 * @pcm: the PCM instance 1097 * @pcm: the PCM instance
@@ -1114,6 +1121,8 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm)
1114 return 0; 1121 return 0;
1115} 1122}
1116 1123
1124EXPORT_SYMBOL(snd_pcm_suspend_all);
1125
1117/* resume */ 1126/* resume */
1118 1127
1119static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state) 1128static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state)
@@ -1275,13 +1284,16 @@ static int snd_pcm_reset(struct snd_pcm_substream *substream)
1275/* 1284/*
1276 * prepare ioctl 1285 * prepare ioctl
1277 */ 1286 */
1278static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream, int state) 1287/* we use the second argument for updating f_flags */
1288static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
1289 int f_flags)
1279{ 1290{
1280 struct snd_pcm_runtime *runtime = substream->runtime; 1291 struct snd_pcm_runtime *runtime = substream->runtime;
1281 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1292 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1282 return -EBADFD; 1293 return -EBADFD;
1283 if (snd_pcm_running(substream)) 1294 if (snd_pcm_running(substream))
1284 return -EBUSY; 1295 return -EBUSY;
1296 substream->f_flags = f_flags;
1285 return 0; 1297 return 0;
1286} 1298}
1287 1299
@@ -1310,17 +1322,26 @@ static struct action_ops snd_pcm_action_prepare = {
1310/** 1322/**
1311 * snd_pcm_prepare 1323 * snd_pcm_prepare
1312 * @substream: the PCM substream instance 1324 * @substream: the PCM substream instance
1325 * @file: file to refer f_flags
1313 * 1326 *
1314 * Prepare the PCM substream to be triggerable. 1327 * Prepare the PCM substream to be triggerable.
1315 */ 1328 */
1316static int snd_pcm_prepare(struct snd_pcm_substream *substream) 1329static int snd_pcm_prepare(struct snd_pcm_substream *substream,
1330 struct file *file)
1317{ 1331{
1318 int res; 1332 int res;
1319 struct snd_card *card = substream->pcm->card; 1333 struct snd_card *card = substream->pcm->card;
1334 int f_flags;
1335
1336 if (file)
1337 f_flags = file->f_flags;
1338 else
1339 f_flags = substream->f_flags;
1320 1340
1321 snd_power_lock(card); 1341 snd_power_lock(card);
1322 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0) 1342 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0)
1323 res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare, substream, 0); 1343 res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
1344 substream, f_flags);
1324 snd_power_unlock(card); 1345 snd_power_unlock(card);
1325 return res; 1346 return res;
1326} 1347}
@@ -1331,7 +1352,7 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream)
1331 1352
1332static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state) 1353static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state)
1333{ 1354{
1334 if (substream->ffile->f_flags & O_NONBLOCK) 1355 if (substream->f_flags & O_NONBLOCK)
1335 return -EAGAIN; 1356 return -EAGAIN;
1336 substream->runtime->trigger_master = substream; 1357 substream->runtime->trigger_master = substream;
1337 return 0; 1358 return 0;
@@ -1448,8 +1469,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
1448 } 1469 }
1449 } 1470 }
1450 up_read(&snd_pcm_link_rwsem); 1471 up_read(&snd_pcm_link_rwsem);
1451 if (! num_drecs)
1452 goto _error;
1453 1472
1454 snd_pcm_stream_lock_irq(substream); 1473 snd_pcm_stream_lock_irq(substream);
1455 /* resume pause */ 1474 /* resume pause */
@@ -2006,6 +2025,10 @@ static void pcm_release_private(struct snd_pcm_substream *substream)
2006 2025
2007void snd_pcm_release_substream(struct snd_pcm_substream *substream) 2026void snd_pcm_release_substream(struct snd_pcm_substream *substream)
2008{ 2027{
2028 substream->ref_count--;
2029 if (substream->ref_count > 0)
2030 return;
2031
2009 snd_pcm_drop(substream); 2032 snd_pcm_drop(substream);
2010 if (substream->hw_opened) { 2033 if (substream->hw_opened) {
2011 if (substream->ops->hw_free != NULL) 2034 if (substream->ops->hw_free != NULL)
@@ -2020,6 +2043,8 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream)
2020 snd_pcm_detach_substream(substream); 2043 snd_pcm_detach_substream(substream);
2021} 2044}
2022 2045
2046EXPORT_SYMBOL(snd_pcm_release_substream);
2047
2023int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, 2048int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2024 struct file *file, 2049 struct file *file,
2025 struct snd_pcm_substream **rsubstream) 2050 struct snd_pcm_substream **rsubstream)
@@ -2030,6 +2055,11 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2030 err = snd_pcm_attach_substream(pcm, stream, file, &substream); 2055 err = snd_pcm_attach_substream(pcm, stream, file, &substream);
2031 if (err < 0) 2056 if (err < 0)
2032 return err; 2057 return err;
2058 if (substream->ref_count > 1) {
2059 *rsubstream = substream;
2060 return 0;
2061 }
2062
2033 substream->no_mmap_ctrl = 0; 2063 substream->no_mmap_ctrl = 0;
2034 err = snd_pcm_hw_constraints_init(substream); 2064 err = snd_pcm_hw_constraints_init(substream);
2035 if (err < 0) { 2065 if (err < 0) {
@@ -2056,6 +2086,8 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2056 return err; 2086 return err;
2057} 2087}
2058 2088
2089EXPORT_SYMBOL(snd_pcm_open_substream);
2090
2059static int snd_pcm_open_file(struct file *file, 2091static int snd_pcm_open_file(struct file *file,
2060 struct snd_pcm *pcm, 2092 struct snd_pcm *pcm,
2061 int stream, 2093 int stream,
@@ -2073,17 +2105,20 @@ static int snd_pcm_open_file(struct file *file,
2073 if (err < 0) 2105 if (err < 0)
2074 return err; 2106 return err;
2075 2107
2076 pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); 2108 if (substream->ref_count > 1)
2077 if (pcm_file == NULL) { 2109 pcm_file = substream->file;
2078 snd_pcm_release_substream(substream); 2110 else {
2079 return -ENOMEM; 2111 pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
2112 if (pcm_file == NULL) {
2113 snd_pcm_release_substream(substream);
2114 return -ENOMEM;
2115 }
2116 str = substream->pstr;
2117 substream->file = pcm_file;
2118 substream->pcm_release = pcm_release_private;
2119 pcm_file->substream = substream;
2120 snd_pcm_add_file(str, pcm_file);
2080 } 2121 }
2081 str = substream->pstr;
2082 substream->file = pcm_file;
2083 substream->pcm_release = pcm_release_private;
2084 pcm_file->substream = substream;
2085 snd_pcm_add_file(str, pcm_file);
2086
2087 file->private_data = pcm_file; 2122 file->private_data = pcm_file;
2088 *rpcm_file = pcm_file; 2123 *rpcm_file = pcm_file;
2089 return 0; 2124 return 0;
@@ -2170,7 +2205,6 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
2170 pcm_file = file->private_data; 2205 pcm_file = file->private_data;
2171 substream = pcm_file->substream; 2206 substream = pcm_file->substream;
2172 snd_assert(substream != NULL, return -ENXIO); 2207 snd_assert(substream != NULL, return -ENXIO);
2173 snd_assert(!atomic_read(&substream->runtime->mmap_count), );
2174 pcm = substream->pcm; 2208 pcm = substream->pcm;
2175 fasync_helper(-1, file, 0, &substream->runtime->fasync); 2209 fasync_helper(-1, file, 0, &substream->runtime->fasync);
2176 mutex_lock(&pcm->open_mutex); 2210 mutex_lock(&pcm->open_mutex);
@@ -2493,7 +2527,8 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
2493 return 0; 2527 return 0;
2494} 2528}
2495 2529
2496static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, 2530static int snd_pcm_common_ioctl1(struct file *file,
2531 struct snd_pcm_substream *substream,
2497 unsigned int cmd, void __user *arg) 2532 unsigned int cmd, void __user *arg)
2498{ 2533{
2499 snd_assert(substream != NULL, return -ENXIO); 2534 snd_assert(substream != NULL, return -ENXIO);
@@ -2518,7 +2553,7 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
2518 case SNDRV_PCM_IOCTL_CHANNEL_INFO: 2553 case SNDRV_PCM_IOCTL_CHANNEL_INFO:
2519 return snd_pcm_channel_info_user(substream, arg); 2554 return snd_pcm_channel_info_user(substream, arg);
2520 case SNDRV_PCM_IOCTL_PREPARE: 2555 case SNDRV_PCM_IOCTL_PREPARE:
2521 return snd_pcm_prepare(substream); 2556 return snd_pcm_prepare(substream, file);
2522 case SNDRV_PCM_IOCTL_RESET: 2557 case SNDRV_PCM_IOCTL_RESET:
2523 return snd_pcm_reset(substream); 2558 return snd_pcm_reset(substream);
2524 case SNDRV_PCM_IOCTL_START: 2559 case SNDRV_PCM_IOCTL_START:
@@ -2560,7 +2595,8 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
2560 return -ENOTTY; 2595 return -ENOTTY;
2561} 2596}
2562 2597
2563static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream, 2598static int snd_pcm_playback_ioctl1(struct file *file,
2599 struct snd_pcm_substream *substream,
2564 unsigned int cmd, void __user *arg) 2600 unsigned int cmd, void __user *arg)
2565{ 2601{
2566 snd_assert(substream != NULL, return -ENXIO); 2602 snd_assert(substream != NULL, return -ENXIO);
@@ -2636,10 +2672,11 @@ static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream,
2636 return result < 0 ? result : 0; 2672 return result < 0 ? result : 0;
2637 } 2673 }
2638 } 2674 }
2639 return snd_pcm_common_ioctl1(substream, cmd, arg); 2675 return snd_pcm_common_ioctl1(file, substream, cmd, arg);
2640} 2676}
2641 2677
2642static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream, 2678static int snd_pcm_capture_ioctl1(struct file *file,
2679 struct snd_pcm_substream *substream,
2643 unsigned int cmd, void __user *arg) 2680 unsigned int cmd, void __user *arg)
2644{ 2681{
2645 snd_assert(substream != NULL, return -ENXIO); 2682 snd_assert(substream != NULL, return -ENXIO);
@@ -2715,7 +2752,7 @@ static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream,
2715 return result < 0 ? result : 0; 2752 return result < 0 ? result : 0;
2716 } 2753 }
2717 } 2754 }
2718 return snd_pcm_common_ioctl1(substream, cmd, arg); 2755 return snd_pcm_common_ioctl1(file, substream, cmd, arg);
2719} 2756}
2720 2757
2721static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd, 2758static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
@@ -2728,7 +2765,8 @@ static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
2728 if (((cmd >> 8) & 0xff) != 'A') 2765 if (((cmd >> 8) & 0xff) != 'A')
2729 return -ENOTTY; 2766 return -ENOTTY;
2730 2767
2731 return snd_pcm_playback_ioctl1(pcm_file->substream, cmd, (void __user *)arg); 2768 return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd,
2769 (void __user *)arg);
2732} 2770}
2733 2771
2734static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, 2772static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
@@ -2741,7 +2779,8 @@ static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
2741 if (((cmd >> 8) & 0xff) != 'A') 2779 if (((cmd >> 8) & 0xff) != 'A')
2742 return -ENOTTY; 2780 return -ENOTTY;
2743 2781
2744 return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg); 2782 return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd,
2783 (void __user *)arg);
2745} 2784}
2746 2785
2747int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, 2786int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
@@ -2753,12 +2792,12 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
2753 fs = snd_enter_user(); 2792 fs = snd_enter_user();
2754 switch (substream->stream) { 2793 switch (substream->stream) {
2755 case SNDRV_PCM_STREAM_PLAYBACK: 2794 case SNDRV_PCM_STREAM_PLAYBACK:
2756 result = snd_pcm_playback_ioctl1(substream, 2795 result = snd_pcm_playback_ioctl1(NULL, substream, cmd,
2757 cmd, (void __user *)arg); 2796 (void __user *)arg);
2758 break; 2797 break;
2759 case SNDRV_PCM_STREAM_CAPTURE: 2798 case SNDRV_PCM_STREAM_CAPTURE:
2760 result = snd_pcm_capture_ioctl1(substream, 2799 result = snd_pcm_capture_ioctl1(NULL, substream, cmd,
2761 cmd, (void __user *)arg); 2800 (void __user *)arg);
2762 break; 2801 break;
2763 default: 2802 default:
2764 result = -EINVAL; 2803 result = -EINVAL;
@@ -2768,6 +2807,8 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
2768 return result; 2807 return result;
2769} 2808}
2770 2809
2810EXPORT_SYMBOL(snd_pcm_kernel_ioctl);
2811
2771static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, 2812static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count,
2772 loff_t * offset) 2813 loff_t * offset)
2773{ 2814{
@@ -3134,7 +3175,7 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
3134 area->vm_ops = &snd_pcm_vm_ops_data; 3175 area->vm_ops = &snd_pcm_vm_ops_data;
3135 area->vm_private_data = substream; 3176 area->vm_private_data = substream;
3136 area->vm_flags |= VM_RESERVED; 3177 area->vm_flags |= VM_RESERVED;
3137 atomic_inc(&substream->runtime->mmap_count); 3178 atomic_inc(&substream->mmap_count);
3138 return 0; 3179 return 0;
3139} 3180}
3140 3181
@@ -3166,9 +3207,11 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3166 (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, 3207 (substream->runtime->dma_addr + offset) >> PAGE_SHIFT,
3167 size, area->vm_page_prot)) 3208 size, area->vm_page_prot))
3168 return -EAGAIN; 3209 return -EAGAIN;
3169 atomic_inc(&substream->runtime->mmap_count); 3210 atomic_inc(&substream->mmap_count);
3170 return 0; 3211 return 0;
3171} 3212}
3213
3214EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
3172#endif /* SNDRV_PCM_INFO_MMAP */ 3215#endif /* SNDRV_PCM_INFO_MMAP */
3173 3216
3174/* 3217/*
@@ -3212,6 +3255,8 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
3212 return snd_pcm_default_mmap(substream, area); 3255 return snd_pcm_default_mmap(substream, area);
3213} 3256}
3214 3257
3258EXPORT_SYMBOL(snd_pcm_mmap_data);
3259
3215static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) 3260static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
3216{ 3261{
3217 struct snd_pcm_file * pcm_file; 3262 struct snd_pcm_file * pcm_file;
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 87b47c9564f7..8c15c66eb4aa 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -43,7 +43,7 @@ MODULE_DESCRIPTION("Midlevel RawMidi code for ALSA.");
43MODULE_LICENSE("GPL"); 43MODULE_LICENSE("GPL");
44 44
45#ifdef CONFIG_SND_OSSEMUL 45#ifdef CONFIG_SND_OSSEMUL
46static int midi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0}; 46static int midi_map[SNDRV_CARDS];
47static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; 47static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
48module_param_array(midi_map, int, NULL, 0444); 48module_param_array(midi_map, int, NULL, 0444);
49MODULE_PARM_DESC(midi_map, "Raw MIDI device number assigned to 1st OSS device."); 49MODULE_PARM_DESC(midi_map, "Raw MIDI device number assigned to 1st OSS device.");
@@ -1561,7 +1561,6 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
1561 entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); 1561 entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
1562 if (entry) { 1562 if (entry) {
1563 entry->private_data = rmidi; 1563 entry->private_data = rmidi;
1564 entry->c.text.read_size = 1024;
1565 entry->c.text.read = snd_rawmidi_proc_info_read; 1564 entry->c.text.read = snd_rawmidi_proc_info_read;
1566 if (snd_info_register(entry) < 0) { 1565 if (snd_info_register(entry) < 0) {
1567 snd_info_free_entry(entry); 1566 snd_info_free_entry(entry);
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index b9919785180b..e7234135641c 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -291,7 +291,6 @@ register_proc(void)
291 291
292 entry->content = SNDRV_INFO_CONTENT_TEXT; 292 entry->content = SNDRV_INFO_CONTENT_TEXT;
293 entry->private_data = NULL; 293 entry->private_data = NULL;
294 entry->c.text.read_size = 1024;
295 entry->c.text.read = info_read; 294 entry->c.text.read = info_read;
296 if (snd_info_register(entry) < 0) { 295 if (snd_info_register(entry) < 0) {
297 snd_info_free_entry(entry); 296 snd_info_free_entry(entry);
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index 20f954bc7aa0..2f0d8773ac6b 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -129,25 +129,3 @@ static void __exit alsa_seq_exit(void)
129 129
130module_init(alsa_seq_init) 130module_init(alsa_seq_init)
131module_exit(alsa_seq_exit) 131module_exit(alsa_seq_exit)
132
133 /* seq_clientmgr.c */
134EXPORT_SYMBOL(snd_seq_create_kernel_client);
135EXPORT_SYMBOL(snd_seq_delete_kernel_client);
136EXPORT_SYMBOL(snd_seq_kernel_client_enqueue);
137EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking);
138EXPORT_SYMBOL(snd_seq_kernel_client_dispatch);
139EXPORT_SYMBOL(snd_seq_kernel_client_ctl);
140EXPORT_SYMBOL(snd_seq_kernel_client_write_poll);
141EXPORT_SYMBOL(snd_seq_set_queue_tempo);
142 /* seq_memory.c */
143EXPORT_SYMBOL(snd_seq_expand_var_event);
144EXPORT_SYMBOL(snd_seq_dump_var_event);
145 /* seq_ports.c */
146EXPORT_SYMBOL(snd_seq_event_port_attach);
147EXPORT_SYMBOL(snd_seq_event_port_detach);
148 /* seq_lock.c */
149#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
150/*EXPORT_SYMBOL(snd_seq_sleep_in_lock);*/
151/*EXPORT_SYMBOL(snd_seq_sleep_timeout_in_lock);*/
152EXPORT_SYMBOL(snd_use_lock_sync_helper);
153#endif
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index bb15d9ee8842..532a660df51d 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -1714,6 +1714,8 @@ int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo)
1714 return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo); 1714 return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo);
1715} 1715}
1716 1716
1717EXPORT_SYMBOL(snd_seq_set_queue_tempo);
1718
1717static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client, 1719static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client,
1718 void __user *arg) 1720 void __user *arg)
1719{ 1721{
@@ -2264,6 +2266,8 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
2264 return client->number; 2266 return client->number;
2265} 2267}
2266 2268
2269EXPORT_SYMBOL(snd_seq_create_kernel_client);
2270
2267/* exported to kernel modules */ 2271/* exported to kernel modules */
2268int snd_seq_delete_kernel_client(int client) 2272int snd_seq_delete_kernel_client(int client)
2269{ 2273{
@@ -2280,6 +2284,7 @@ int snd_seq_delete_kernel_client(int client)
2280 return 0; 2284 return 0;
2281} 2285}
2282 2286
2287EXPORT_SYMBOL(snd_seq_delete_kernel_client);
2283 2288
2284/* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue 2289/* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue
2285 * and snd_seq_kernel_client_enqueue_blocking 2290 * and snd_seq_kernel_client_enqueue_blocking
@@ -2328,6 +2333,8 @@ int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event * ev,
2328 return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop); 2333 return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop);
2329} 2334}
2330 2335
2336EXPORT_SYMBOL(snd_seq_kernel_client_enqueue);
2337
2331/* 2338/*
2332 * exported, called by kernel clients to enqueue events (with blocking) 2339 * exported, called by kernel clients to enqueue events (with blocking)
2333 * 2340 *
@@ -2340,6 +2347,7 @@ int snd_seq_kernel_client_enqueue_blocking(int client, struct snd_seq_event * ev
2340 return kernel_client_enqueue(client, ev, file, 1, atomic, hop); 2347 return kernel_client_enqueue(client, ev, file, 1, atomic, hop);
2341} 2348}
2342 2349
2350EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking);
2343 2351
2344/* 2352/*
2345 * exported, called by kernel clients to dispatch events directly to other 2353 * exported, called by kernel clients to dispatch events directly to other
@@ -2376,6 +2384,7 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev,
2376 return result; 2384 return result;
2377} 2385}
2378 2386
2387EXPORT_SYMBOL(snd_seq_kernel_client_dispatch);
2379 2388
2380/* 2389/*
2381 * exported, called by kernel clients to perform same functions as with 2390 * exported, called by kernel clients to perform same functions as with
@@ -2396,6 +2405,7 @@ int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
2396 return result; 2405 return result;
2397} 2406}
2398 2407
2408EXPORT_SYMBOL(snd_seq_kernel_client_ctl);
2399 2409
2400/* exported (for OSS emulator) */ 2410/* exported (for OSS emulator) */
2401int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait) 2411int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait)
@@ -2413,6 +2423,8 @@ int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table
2413 return 0; 2423 return 0;
2414} 2424}
2415 2425
2426EXPORT_SYMBOL(snd_seq_kernel_client_write_poll);
2427
2416/*---------------------------------------------------------------------------*/ 2428/*---------------------------------------------------------------------------*/
2417 2429
2418#ifdef CONFIG_PROC_FS 2430#ifdef CONFIG_PROC_FS
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index d9a3e5a18d6a..d812dc886360 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -80,7 +80,7 @@ static LIST_HEAD(opslist);
80static int num_ops; 80static int num_ops;
81static DEFINE_MUTEX(ops_mutex); 81static DEFINE_MUTEX(ops_mutex);
82#ifdef CONFIG_PROC_FS 82#ifdef CONFIG_PROC_FS
83static struct snd_info_entry *info_entry = NULL; 83static struct snd_info_entry *info_entry;
84#endif 84#endif
85 85
86/* 86/*
@@ -555,7 +555,6 @@ static int __init alsa_seq_device_init(void)
555 if (info_entry == NULL) 555 if (info_entry == NULL)
556 return -ENOMEM; 556 return -ENOMEM;
557 info_entry->content = SNDRV_INFO_CONTENT_TEXT; 557 info_entry->content = SNDRV_INFO_CONTENT_TEXT;
558 info_entry->c.text.read_size = 2048;
559 info_entry->c.text.read = snd_seq_device_info; 558 info_entry->c.text.read = snd_seq_device_info;
560 if (snd_info_register(info_entry) < 0) { 559 if (snd_info_register(info_entry) < 0) {
561 snd_info_free_entry(info_entry); 560 snd_info_free_entry(info_entry);
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
index 2a283a59ea4d..e55488d1237c 100644
--- a/sound/core/seq/seq_dummy.c
+++ b/sound/core/seq/seq_dummy.c
@@ -66,7 +66,7 @@ MODULE_LICENSE("GPL");
66MODULE_ALIAS("snd-seq-client-" __stringify(SNDRV_SEQ_CLIENT_DUMMY)); 66MODULE_ALIAS("snd-seq-client-" __stringify(SNDRV_SEQ_CLIENT_DUMMY));
67 67
68static int ports = 1; 68static int ports = 1;
69static int duplex = 0; 69static int duplex;
70 70
71module_param(ports, int, 0444); 71module_param(ports, int, 0444);
72MODULE_PARM_DESC(ports, "number of ports to be created"); 72MODULE_PARM_DESC(ports, "number of ports to be created");
@@ -171,7 +171,9 @@ create_port(int idx, int type)
171 pinfo.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; 171 pinfo.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
172 if (duplex) 172 if (duplex)
173 pinfo.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; 173 pinfo.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
174 pinfo.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; 174 pinfo.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
175 | SNDRV_SEQ_PORT_TYPE_SOFTWARE
176 | SNDRV_SEQ_PORT_TYPE_PORT;
175 memset(&pcb, 0, sizeof(pcb)); 177 memset(&pcb, 0, sizeof(pcb));
176 pcb.owner = THIS_MODULE; 178 pcb.owner = THIS_MODULE;
177 pcb.unuse = dummy_unuse; 179 pcb.unuse = dummy_unuse;
diff --git a/sound/core/seq/seq_info.c b/sound/core/seq/seq_info.c
index acce21afdaa4..142e9e6882c9 100644
--- a/sound/core/seq/seq_info.c
+++ b/sound/core/seq/seq_info.c
@@ -34,8 +34,8 @@ static struct snd_info_entry *timer_entry;
34 34
35 35
36static struct snd_info_entry * __init 36static struct snd_info_entry * __init
37create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *, 37create_info_entry(char *name, void (*read)(struct snd_info_entry *,
38 struct snd_info_buffer *)) 38 struct snd_info_buffer *))
39{ 39{
40 struct snd_info_entry *entry; 40 struct snd_info_entry *entry;
41 41
@@ -43,7 +43,6 @@ create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *,
43 if (entry == NULL) 43 if (entry == NULL)
44 return NULL; 44 return NULL;
45 entry->content = SNDRV_INFO_CONTENT_TEXT; 45 entry->content = SNDRV_INFO_CONTENT_TEXT;
46 entry->c.text.read_size = size;
47 entry->c.text.read = read; 46 entry->c.text.read = read;
48 if (snd_info_register(entry) < 0) { 47 if (snd_info_register(entry) < 0) {
49 snd_info_free_entry(entry); 48 snd_info_free_entry(entry);
@@ -55,11 +54,11 @@ create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *,
55/* create all our /proc entries */ 54/* create all our /proc entries */
56int __init snd_seq_info_init(void) 55int __init snd_seq_info_init(void)
57{ 56{
58 queues_entry = create_info_entry("queues", 512 + (256 * SNDRV_SEQ_MAX_QUEUES), 57 queues_entry = create_info_entry("queues",
59 snd_seq_info_queues_read); 58 snd_seq_info_queues_read);
60 clients_entry = create_info_entry("clients", 512 + (256 * SNDRV_SEQ_MAX_CLIENTS), 59 clients_entry = create_info_entry("clients",
61 snd_seq_info_clients_read); 60 snd_seq_info_clients_read);
62 timer_entry = create_info_entry("timer", 1024, snd_seq_info_timer_read); 61 timer_entry = create_info_entry("timer", snd_seq_info_timer_read);
63 return 0; 62 return 0;
64} 63}
65 64
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c
index a837a94b2d2a..1a34941d4217 100644
--- a/sound/core/seq/seq_lock.c
+++ b/sound/core/seq/seq_lock.c
@@ -44,4 +44,6 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
44 } 44 }
45} 45}
46 46
47EXPORT_SYMBOL(snd_use_lock_sync_helper);
48
47#endif 49#endif
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index 40b4f679c80e..4bffe509f719 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -118,6 +118,8 @@ int snd_seq_dump_var_event(const struct snd_seq_event *event,
118 return 0; 118 return 0;
119} 119}
120 120
121EXPORT_SYMBOL(snd_seq_dump_var_event);
122
121 123
122/* 124/*
123 * exported: 125 * exported:
@@ -167,6 +169,7 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char
167 return err < 0 ? err : newlen; 169 return err < 0 ? err : newlen;
168} 170}
169 171
172EXPORT_SYMBOL(snd_seq_expand_var_event);
170 173
171/* 174/*
172 * release this cell, free extended data if available 175 * release this cell, free extended data if available
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index 9caa1372bece..1daa5b069c79 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -278,6 +278,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
278 struct seq_midisynth *msynth, *ms; 278 struct seq_midisynth *msynth, *ms;
279 struct snd_seq_port_info *port; 279 struct snd_seq_port_info *port;
280 struct snd_rawmidi_info *info; 280 struct snd_rawmidi_info *info;
281 struct snd_rawmidi *rmidi = dev->private_data;
281 int newclient = 0; 282 int newclient = 0;
282 unsigned int p, ports; 283 unsigned int p, ports;
283 struct snd_seq_port_callback pcallbacks; 284 struct snd_seq_port_callback pcallbacks;
@@ -320,8 +321,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
320 } 321 }
321 client->seq_client = 322 client->seq_client =
322 snd_seq_create_kernel_client( 323 snd_seq_create_kernel_client(
323 card, 0, "%s", info->name[0] ? 324 card, 0, "%s", card->shortname[0] ?
324 (const char *)info->name : "External MIDI"); 325 (const char *)card->shortname : "External MIDI");
325 if (client->seq_client < 0) { 326 if (client->seq_client < 0) {
326 kfree(client); 327 kfree(client);
327 mutex_unlock(&register_mutex); 328 mutex_unlock(&register_mutex);
@@ -376,7 +377,9 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
376 if ((port->capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) && 377 if ((port->capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) &&
377 info->flags & SNDRV_RAWMIDI_INFO_DUPLEX) 378 info->flags & SNDRV_RAWMIDI_INFO_DUPLEX)
378 port->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; 379 port->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
379 port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; 380 port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
381 | SNDRV_SEQ_PORT_TYPE_HARDWARE
382 | SNDRV_SEQ_PORT_TYPE_PORT;
380 port->midi_channels = 16; 383 port->midi_channels = 16;
381 memset(&pcallbacks, 0, sizeof(pcallbacks)); 384 memset(&pcallbacks, 0, sizeof(pcallbacks));
382 pcallbacks.owner = THIS_MODULE; 385 pcallbacks.owner = THIS_MODULE;
@@ -387,6 +390,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
387 pcallbacks.unuse = midisynth_unuse; 390 pcallbacks.unuse = midisynth_unuse;
388 pcallbacks.event_input = event_process_midi; 391 pcallbacks.event_input = event_process_midi;
389 port->kernel = &pcallbacks; 392 port->kernel = &pcallbacks;
393 if (rmidi->ops && rmidi->ops->get_port_info)
394 rmidi->ops->get_port_info(rmidi, p, port);
390 if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, port)<0) 395 if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, port)<0)
391 goto __nomem; 396 goto __nomem;
392 ms->seq_client = client->seq_client; 397 ms->seq_client = client->seq_client;
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index 41e078c938cd..334579a9f268 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -221,7 +221,6 @@ static void clear_subscriber_list(struct snd_seq_client *client,
221{ 221{
222 struct list_head *p, *n; 222 struct list_head *p, *n;
223 223
224 down_write(&grp->list_mutex);
225 list_for_each_safe(p, n, &grp->list_head) { 224 list_for_each_safe(p, n, &grp->list_head) {
226 struct snd_seq_subscribers *subs; 225 struct snd_seq_subscribers *subs;
227 struct snd_seq_client *c; 226 struct snd_seq_client *c;
@@ -259,7 +258,6 @@ static void clear_subscriber_list(struct snd_seq_client *client,
259 snd_seq_client_unlock(c); 258 snd_seq_client_unlock(c);
260 } 259 }
261 } 260 }
262 up_write(&grp->list_mutex);
263} 261}
264 262
265/* delete port data */ 263/* delete port data */
@@ -677,6 +675,7 @@ int snd_seq_event_port_attach(int client,
677 return ret; 675 return ret;
678} 676}
679 677
678EXPORT_SYMBOL(snd_seq_event_port_attach);
680 679
681/* 680/*
682 * Detach the driver from a port. 681 * Detach the driver from a port.
@@ -696,3 +695,5 @@ int snd_seq_event_port_detach(int client, int port)
696 695
697 return err; 696 return err;
698} 697}
698
699EXPORT_SYMBOL(snd_seq_event_port_detach);
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index f4edec603b8f..0cfa06c6b81f 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -390,7 +390,9 @@ static int snd_virmidi_dev_attach_seq(struct snd_virmidi_dev *rdev)
390 pinfo->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; 390 pinfo->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
391 pinfo->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ; 391 pinfo->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
392 pinfo->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; 392 pinfo->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
393 pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; 393 pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
394 | SNDRV_SEQ_PORT_TYPE_SOFTWARE
395 | SNDRV_SEQ_PORT_TYPE_PORT;
394 pinfo->midi_channels = 16; 396 pinfo->midi_channels = 16;
395 memset(&pcallbacks, 0, sizeof(pcallbacks)); 397 memset(&pcallbacks, 0, sizeof(pcallbacks));
396 pcallbacks.owner = THIS_MODULE; 398 pcallbacks.owner = THIS_MODULE;
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 108e430b5036..cd862728346c 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -39,6 +39,8 @@
39 39
40static int major = CONFIG_SND_MAJOR; 40static int major = CONFIG_SND_MAJOR;
41int snd_major; 41int snd_major;
42EXPORT_SYMBOL(snd_major);
43
42static int cards_limit = 1; 44static int cards_limit = 1;
43static int device_mode = S_IFCHR | S_IRUGO | S_IWUGO; 45static int device_mode = S_IFCHR | S_IRUGO | S_IWUGO;
44 46
@@ -60,6 +62,7 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
60 * modules are loaded manually, this limit number increases, too. 62 * modules are loaded manually, this limit number increases, too.
61 */ 63 */
62int snd_ecards_limit; 64int snd_ecards_limit;
65EXPORT_SYMBOL(snd_ecards_limit);
63 66
64static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; 67static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
65static DEFINE_MUTEX(sound_mutex); 68static DEFINE_MUTEX(sound_mutex);
@@ -78,20 +81,17 @@ extern struct class *sound_class;
78 */ 81 */
79void snd_request_card(int card) 82void snd_request_card(int card)
80{ 83{
81 int locked;
82
83 if (! current->fs->root) 84 if (! current->fs->root)
84 return; 85 return;
85 read_lock(&snd_card_rwlock); 86 if (snd_card_locked(card))
86 locked = snd_cards_lock & (1 << card);
87 read_unlock(&snd_card_rwlock);
88 if (locked)
89 return; 87 return;
90 if (card < 0 || card >= cards_limit) 88 if (card < 0 || card >= cards_limit)
91 return; 89 return;
92 request_module("snd-card-%i", card); 90 request_module("snd-card-%i", card);
93} 91}
94 92
93EXPORT_SYMBOL(snd_request_card);
94
95static void snd_request_other(int minor) 95static void snd_request_other(int minor)
96{ 96{
97 char *str; 97 char *str;
@@ -133,6 +133,8 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
133 return private_data; 133 return private_data;
134} 134}
135 135
136EXPORT_SYMBOL(snd_lookup_minor_data);
137
136static int snd_open(struct inode *inode, struct file *file) 138static int snd_open(struct inode *inode, struct file *file)
137{ 139{
138 unsigned int minor = iminor(inode); 140 unsigned int minor = iminor(inode);
@@ -281,6 +283,8 @@ int snd_register_device(int type, struct snd_card *card, int dev,
281 return 0; 283 return 0;
282} 284}
283 285
286EXPORT_SYMBOL(snd_register_device);
287
284/** 288/**
285 * snd_unregister_device - unregister the device on the given card 289 * snd_unregister_device - unregister the device on the given card
286 * @type: the device type, SNDRV_DEVICE_TYPE_XXX 290 * @type: the device type, SNDRV_DEVICE_TYPE_XXX
@@ -321,12 +325,14 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
321 return 0; 325 return 0;
322} 326}
323 327
328EXPORT_SYMBOL(snd_unregister_device);
329
324#ifdef CONFIG_PROC_FS 330#ifdef CONFIG_PROC_FS
325/* 331/*
326 * INFO PART 332 * INFO PART
327 */ 333 */
328 334
329static struct snd_info_entry *snd_minor_info_entry = NULL; 335static struct snd_info_entry *snd_minor_info_entry;
330 336
331static const char *snd_device_type_name(int type) 337static const char *snd_device_type_name(int type)
332{ 338{
@@ -381,7 +387,6 @@ int __init snd_minor_info_init(void)
381 387
382 entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL); 388 entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL);
383 if (entry) { 389 if (entry) {
384 entry->c.text.read_size = PAGE_SIZE;
385 entry->c.text.read = snd_minor_info_read; 390 entry->c.text.read = snd_minor_info_read;
386 if (snd_info_register(entry) < 0) { 391 if (snd_info_register(entry) < 0) {
387 snd_info_free_entry(entry); 392 snd_info_free_entry(entry);
@@ -446,91 +451,3 @@ static void __exit alsa_sound_exit(void)
446 451
447module_init(alsa_sound_init) 452module_init(alsa_sound_init)
448module_exit(alsa_sound_exit) 453module_exit(alsa_sound_exit)
449
450 /* sound.c */
451EXPORT_SYMBOL(snd_major);
452EXPORT_SYMBOL(snd_ecards_limit);
453#if defined(CONFIG_KMOD)
454EXPORT_SYMBOL(snd_request_card);
455#endif
456EXPORT_SYMBOL(snd_register_device);
457EXPORT_SYMBOL(snd_unregister_device);
458EXPORT_SYMBOL(snd_lookup_minor_data);
459#if defined(CONFIG_SND_OSSEMUL)
460EXPORT_SYMBOL(snd_register_oss_device);
461EXPORT_SYMBOL(snd_unregister_oss_device);
462EXPORT_SYMBOL(snd_lookup_oss_minor_data);
463#endif
464 /* memory.c */
465EXPORT_SYMBOL(copy_to_user_fromio);
466EXPORT_SYMBOL(copy_from_user_toio);
467 /* init.c */
468EXPORT_SYMBOL(snd_cards);
469#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
470EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
471#endif
472EXPORT_SYMBOL(snd_card_new);
473EXPORT_SYMBOL(snd_card_disconnect);
474EXPORT_SYMBOL(snd_card_free);
475EXPORT_SYMBOL(snd_card_free_in_thread);
476EXPORT_SYMBOL(snd_card_register);
477EXPORT_SYMBOL(snd_component_add);
478EXPORT_SYMBOL(snd_card_file_add);
479EXPORT_SYMBOL(snd_card_file_remove);
480#ifdef CONFIG_PM
481EXPORT_SYMBOL(snd_power_wait);
482#endif
483 /* device.c */
484EXPORT_SYMBOL(snd_device_new);
485EXPORT_SYMBOL(snd_device_register);
486EXPORT_SYMBOL(snd_device_free);
487 /* isadma.c */
488#ifdef CONFIG_ISA_DMA_API
489EXPORT_SYMBOL(snd_dma_program);
490EXPORT_SYMBOL(snd_dma_disable);
491EXPORT_SYMBOL(snd_dma_pointer);
492#endif
493 /* info.c */
494#ifdef CONFIG_PROC_FS
495EXPORT_SYMBOL(snd_seq_root);
496EXPORT_SYMBOL(snd_iprintf);
497EXPORT_SYMBOL(snd_info_get_line);
498EXPORT_SYMBOL(snd_info_get_str);
499EXPORT_SYMBOL(snd_info_create_module_entry);
500EXPORT_SYMBOL(snd_info_create_card_entry);
501EXPORT_SYMBOL(snd_info_free_entry);
502EXPORT_SYMBOL(snd_info_register);
503EXPORT_SYMBOL(snd_info_unregister);
504EXPORT_SYMBOL(snd_card_proc_new);
505#endif
506 /* info_oss.c */
507#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
508EXPORT_SYMBOL(snd_oss_info_register);
509#endif
510 /* control.c */
511EXPORT_SYMBOL(snd_ctl_new);
512EXPORT_SYMBOL(snd_ctl_new1);
513EXPORT_SYMBOL(snd_ctl_free_one);
514EXPORT_SYMBOL(snd_ctl_add);
515EXPORT_SYMBOL(snd_ctl_remove);
516EXPORT_SYMBOL(snd_ctl_remove_id);
517EXPORT_SYMBOL(snd_ctl_rename_id);
518EXPORT_SYMBOL(snd_ctl_find_numid);
519EXPORT_SYMBOL(snd_ctl_find_id);
520EXPORT_SYMBOL(snd_ctl_notify);
521EXPORT_SYMBOL(snd_ctl_register_ioctl);
522EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
523#ifdef CONFIG_COMPAT
524EXPORT_SYMBOL(snd_ctl_register_ioctl_compat);
525EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
526#endif
527EXPORT_SYMBOL(snd_ctl_elem_read);
528EXPORT_SYMBOL(snd_ctl_elem_write);
529 /* misc.c */
530EXPORT_SYMBOL(release_and_free_resource);
531#ifdef CONFIG_SND_VERBOSE_PRINTK
532EXPORT_SYMBOL(snd_verbose_printk);
533#endif
534#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
535EXPORT_SYMBOL(snd_verbose_printd);
536#endif
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index 9055c6de9587..74f0fe5a1ba0 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -58,6 +58,8 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type)
58 return private_data; 58 return private_data;
59} 59}
60 60
61EXPORT_SYMBOL(snd_lookup_oss_minor_data);
62
61static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) 63static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
62{ 64{
63 int minor; 65 int minor;
@@ -158,6 +160,8 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
158 return -EBUSY; 160 return -EBUSY;
159} 161}
160 162
163EXPORT_SYMBOL(snd_register_oss_device);
164
161int snd_unregister_oss_device(int type, struct snd_card *card, int dev) 165int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
162{ 166{
163 int minor = snd_oss_kernel_minor(type, card, dev); 167 int minor = snd_oss_kernel_minor(type, card, dev);
@@ -197,13 +201,15 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
197 return 0; 201 return 0;
198} 202}
199 203
204EXPORT_SYMBOL(snd_unregister_oss_device);
205
200/* 206/*
201 * INFO PART 207 * INFO PART
202 */ 208 */
203 209
204#ifdef CONFIG_PROC_FS 210#ifdef CONFIG_PROC_FS
205 211
206static struct snd_info_entry *snd_minor_info_oss_entry = NULL; 212static struct snd_info_entry *snd_minor_info_oss_entry;
207 213
208static const char *snd_oss_device_type_name(int type) 214static const char *snd_oss_device_type_name(int type)
209{ 215{
@@ -252,7 +258,6 @@ int __init snd_minor_info_oss_init(void)
252 258
253 entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root); 259 entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root);
254 if (entry) { 260 if (entry) {
255 entry->c.text.read_size = PAGE_SIZE;
256 entry->c.text.read = snd_minor_info_oss_read; 261 entry->c.text.read = snd_minor_info_oss_read;
257 if (snd_info_register(entry) < 0) { 262 if (snd_info_register(entry) < 0) {
258 snd_info_free_entry(entry); 263 snd_info_free_entry(entry);
diff --git a/sound/core/timer.c b/sound/core/timer.c
index cdeeb639b675..78199f58b93a 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1061,7 +1061,6 @@ static int snd_timer_register_system(void)
1061static void snd_timer_proc_read(struct snd_info_entry *entry, 1061static void snd_timer_proc_read(struct snd_info_entry *entry,
1062 struct snd_info_buffer *buffer) 1062 struct snd_info_buffer *buffer)
1063{ 1063{
1064 unsigned long flags;
1065 struct snd_timer *timer; 1064 struct snd_timer *timer;
1066 struct snd_timer_instance *ti; 1065 struct snd_timer_instance *ti;
1067 struct list_head *p, *q; 1066 struct list_head *p, *q;
@@ -1095,7 +1094,6 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
1095 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) 1094 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
1096 snd_iprintf(buffer, " SLAVE"); 1095 snd_iprintf(buffer, " SLAVE");
1097 snd_iprintf(buffer, "\n"); 1096 snd_iprintf(buffer, "\n");
1098 spin_lock_irqsave(&timer->lock, flags);
1099 list_for_each(q, &timer->open_list_head) { 1097 list_for_each(q, &timer->open_list_head) {
1100 ti = list_entry(q, struct snd_timer_instance, open_list); 1098 ti = list_entry(q, struct snd_timer_instance, open_list);
1101 snd_iprintf(buffer, " Client %s : %s\n", 1099 snd_iprintf(buffer, " Client %s : %s\n",
@@ -1104,12 +1102,11 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
1104 SNDRV_TIMER_IFLG_RUNNING) 1102 SNDRV_TIMER_IFLG_RUNNING)
1105 ? "running" : "stopped"); 1103 ? "running" : "stopped");
1106 } 1104 }
1107 spin_unlock_irqrestore(&timer->lock, flags);
1108 } 1105 }
1109 mutex_unlock(&register_mutex); 1106 mutex_unlock(&register_mutex);
1110} 1107}
1111 1108
1112static struct snd_info_entry *snd_timer_proc_entry = NULL; 1109static struct snd_info_entry *snd_timer_proc_entry;
1113 1110
1114static void __init snd_timer_proc_init(void) 1111static void __init snd_timer_proc_init(void)
1115{ 1112{
@@ -1117,7 +1114,6 @@ static void __init snd_timer_proc_init(void)
1117 1114
1118 entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL); 1115 entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
1119 if (entry != NULL) { 1116 if (entry != NULL) {
1120 entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128;
1121 entry->c.text.read = snd_timer_proc_read; 1117 entry->c.text.read = snd_timer_proc_read;
1122 if (snd_info_register(entry) < 0) { 1118 if (snd_info_register(entry) < 0) {
1123 snd_info_free_entry(entry); 1119 snd_info_free_entry(entry);
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index ae0df549fac7..ffeafaf2ecca 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -677,6 +677,10 @@ static int __init alsa_card_dummy_init(void)
677 i, NULL, 0); 677 i, NULL, 0);
678 if (IS_ERR(device)) 678 if (IS_ERR(device))
679 continue; 679 continue;
680 if (!platform_get_drvdata(device)) {
681 platform_device_unregister(device);
682 continue;
683 }
680 devices[i] = device; 684 devices[i] = device;
681 cards++; 685 cards++;
682 } 686 }
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 77b06009735d..d3cbbb047582 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -253,6 +253,10 @@ static int __init alsa_card_mpu401_init(void)
253 i, NULL, 0); 253 i, NULL, 0);
254 if (IS_ERR(device)) 254 if (IS_ERR(device))
255 continue; 255 continue;
256 if (!platform_get_drvdata(device)) {
257 platform_device_unregister(device);
258 continue;
259 }
256 platform_devices[i] = device; 260 platform_devices[i] = device;
257 snd_mpu401_devices++; 261 snd_mpu401_devices++;
258 } 262 }
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index b49a45cbf67a..4bf07ca9b17d 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -58,22 +58,26 @@ static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu);
58#define MPU401_ACK 0xfe 58#define MPU401_ACK 0xfe
59 59
60/* Build in lowlevel io */ 60/* Build in lowlevel io */
61static void mpu401_write_port(struct snd_mpu401 *mpu, unsigned char data, unsigned long addr) 61static void mpu401_write_port(struct snd_mpu401 *mpu, unsigned char data,
62 unsigned long addr)
62{ 63{
63 outb(data, addr); 64 outb(data, addr);
64} 65}
65 66
66static unsigned char mpu401_read_port(struct snd_mpu401 *mpu, unsigned long addr) 67static unsigned char mpu401_read_port(struct snd_mpu401 *mpu,
68 unsigned long addr)
67{ 69{
68 return inb(addr); 70 return inb(addr);
69} 71}
70 72
71static void mpu401_write_mmio(struct snd_mpu401 *mpu, unsigned char data, unsigned long addr) 73static void mpu401_write_mmio(struct snd_mpu401 *mpu, unsigned char data,
74 unsigned long addr)
72{ 75{
73 writeb(data, (void __iomem *)addr); 76 writeb(data, (void __iomem *)addr);
74} 77}
75 78
76static unsigned char mpu401_read_mmio(struct snd_mpu401 *mpu, unsigned long addr) 79static unsigned char mpu401_read_mmio(struct snd_mpu401 *mpu,
80 unsigned long addr)
77{ 81{
78 return readb((void __iomem *)addr); 82 return readb((void __iomem *)addr);
79} 83}
@@ -86,20 +90,13 @@ static void snd_mpu401_uart_clear_rx(struct snd_mpu401 *mpu)
86 mpu->read(mpu, MPU401D(mpu)); 90 mpu->read(mpu, MPU401D(mpu));
87#ifdef CONFIG_SND_DEBUG 91#ifdef CONFIG_SND_DEBUG
88 if (timeout <= 0) 92 if (timeout <= 0)
89 snd_printk("cmd: clear rx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu))); 93 snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n",
94 mpu->read(mpu, MPU401C(mpu)));
90#endif 95#endif
91} 96}
92 97
93static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu) 98static void uart_interrupt_tx(struct snd_mpu401 *mpu)
94{ 99{
95 spin_lock(&mpu->input_lock);
96 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
97 snd_mpu401_uart_input_read(mpu);
98 } else {
99 snd_mpu401_uart_clear_rx(mpu);
100 }
101 spin_unlock(&mpu->input_lock);
102 /* ok. for better Tx performance try do some output when input is done */
103 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && 100 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
104 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { 101 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
105 spin_lock(&mpu->output_lock); 102 spin_lock(&mpu->output_lock);
@@ -108,6 +105,22 @@ static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
108 } 105 }
109} 106}
110 107
108static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
109{
110 if (mpu->info_flags & MPU401_INFO_INPUT) {
111 spin_lock(&mpu->input_lock);
112 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
113 snd_mpu401_uart_input_read(mpu);
114 else
115 snd_mpu401_uart_clear_rx(mpu);
116 spin_unlock(&mpu->input_lock);
117 }
118 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
119 /* ok. for better Tx performance try do some output
120 when input is done */
121 uart_interrupt_tx(mpu);
122}
123
111/** 124/**
112 * snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler 125 * snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler
113 * @irq: the irq number 126 * @irq: the irq number
@@ -116,7 +129,8 @@ static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
116 * 129 *
117 * Processes the interrupt for MPU401-UART i/o. 130 * Processes the interrupt for MPU401-UART i/o.
118 */ 131 */
119irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs) 132irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id,
133 struct pt_regs *regs)
120{ 134{
121 struct snd_mpu401 *mpu = dev_id; 135 struct snd_mpu401 *mpu = dev_id;
122 136
@@ -126,6 +140,29 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *reg
126 return IRQ_HANDLED; 140 return IRQ_HANDLED;
127} 141}
128 142
143EXPORT_SYMBOL(snd_mpu401_uart_interrupt);
144
145/**
146 * snd_mpu401_uart_interrupt_tx - generic MPU401-UART transmit irq handler
147 * @irq: the irq number
148 * @dev_id: mpu401 instance
149 * @regs: the reigster
150 *
151 * Processes the interrupt for MPU401-UART output.
152 */
153irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id,
154 struct pt_regs *regs)
155{
156 struct snd_mpu401 *mpu = dev_id;
157
158 if (mpu == NULL)
159 return IRQ_NONE;
160 uart_interrupt_tx(mpu);
161 return IRQ_HANDLED;
162}
163
164EXPORT_SYMBOL(snd_mpu401_uart_interrupt_tx);
165
129/* 166/*
130 * timer callback 167 * timer callback
131 * reprogram the timer and call the interrupt job 168 * reprogram the timer and call the interrupt job
@@ -159,7 +196,8 @@ static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input)
159 mpu->timer.expires = 1 + jiffies; 196 mpu->timer.expires = 1 + jiffies;
160 add_timer(&mpu->timer); 197 add_timer(&mpu->timer);
161 } 198 }
162 mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER : MPU401_MODE_OUTPUT_TIMER; 199 mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER :
200 MPU401_MODE_OUTPUT_TIMER;
163 spin_unlock_irqrestore (&mpu->timer_lock, flags); 201 spin_unlock_irqrestore (&mpu->timer_lock, flags);
164} 202}
165 203
@@ -172,7 +210,8 @@ static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input)
172 210
173 spin_lock_irqsave (&mpu->timer_lock, flags); 211 spin_lock_irqsave (&mpu->timer_lock, flags);
174 if (mpu->timer_invoked) { 212 if (mpu->timer_invoked) {
175 mpu->timer_invoked &= input ? ~MPU401_MODE_INPUT_TIMER : ~MPU401_MODE_OUTPUT_TIMER; 213 mpu->timer_invoked &= input ? ~MPU401_MODE_INPUT_TIMER :
214 ~MPU401_MODE_OUTPUT_TIMER;
176 if (! mpu->timer_invoked) 215 if (! mpu->timer_invoked)
177 del_timer(&mpu->timer); 216 del_timer(&mpu->timer);
178 } 217 }
@@ -180,11 +219,12 @@ static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input)
180} 219}
181 220
182/* 221/*
183 222 * send a UART command
223 * return zero if successful, non-zero for some errors
184 */ 224 */
185 225
186static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, 226static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
187 int ack) 227 int ack)
188{ 228{
189 unsigned long flags; 229 unsigned long flags;
190 int timeout, ok; 230 int timeout, ok;
@@ -196,11 +236,13 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
196 } 236 }
197 /* ok. standard MPU-401 initialization */ 237 /* ok. standard MPU-401 initialization */
198 if (mpu->hardware != MPU401_HW_SB) { 238 if (mpu->hardware != MPU401_HW_SB) {
199 for (timeout = 1000; timeout > 0 && !snd_mpu401_output_ready(mpu); timeout--) 239 for (timeout = 1000; timeout > 0 &&
240 !snd_mpu401_output_ready(mpu); timeout--)
200 udelay(10); 241 udelay(10);
201#ifdef CONFIG_SND_DEBUG 242#ifdef CONFIG_SND_DEBUG
202 if (!timeout) 243 if (!timeout)
203 snd_printk("cmd: tx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu))); 244 snd_printk(KERN_ERR "cmd: tx timeout (status = 0x%x)\n",
245 mpu->read(mpu, MPU401C(mpu)));
204#endif 246#endif
205 } 247 }
206 mpu->write(mpu, cmd, MPU401C(mpu)); 248 mpu->write(mpu, cmd, MPU401C(mpu));
@@ -215,12 +257,14 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
215 } 257 }
216 if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK) 258 if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK)
217 ok = 1; 259 ok = 1;
218 } else { 260 } else
219 ok = 1; 261 ok = 1;
220 }
221 spin_unlock_irqrestore(&mpu->input_lock, flags); 262 spin_unlock_irqrestore(&mpu->input_lock, flags);
222 if (!ok) { 263 if (!ok) {
223 snd_printk("cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu))); 264 snd_printk(KERN_ERR "cmd: 0x%x failed at 0x%lx "
265 "(status = 0x%x, data = 0x%x)\n", cmd, mpu->port,
266 mpu->read(mpu, MPU401C(mpu)),
267 mpu->read(mpu, MPU401D(mpu)));
224 return 1; 268 return 1;
225 } 269 }
226 return 0; 270 return 0;
@@ -314,7 +358,8 @@ static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream)
314/* 358/*
315 * trigger input callback 359 * trigger input callback
316 */ 360 */
317static void snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up) 361static void
362snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
318{ 363{
319 unsigned long flags; 364 unsigned long flags;
320 struct snd_mpu401 *mpu; 365 struct snd_mpu401 *mpu;
@@ -322,7 +367,8 @@ static void snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substrea
322 367
323 mpu = substream->rmidi->private_data; 368 mpu = substream->rmidi->private_data;
324 if (up) { 369 if (up) {
325 if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) { 370 if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER,
371 &mpu->mode)) {
326 /* first time - flush FIFO */ 372 /* first time - flush FIFO */
327 while (max-- > 0) 373 while (max-- > 0)
328 mpu->read(mpu, MPU401D(mpu)); 374 mpu->read(mpu, MPU401D(mpu));
@@ -352,13 +398,11 @@ static void snd_mpu401_uart_input_read(struct snd_mpu401 * mpu)
352 unsigned char byte; 398 unsigned char byte;
353 399
354 while (max-- > 0) { 400 while (max-- > 0) {
355 if (snd_mpu401_input_avail(mpu)) { 401 if (! snd_mpu401_input_avail(mpu))
356 byte = mpu->read(mpu, MPU401D(mpu));
357 if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode))
358 snd_rawmidi_receive(mpu->substream_input, &byte, 1);
359 } else {
360 break; /* input not available */ 402 break; /* input not available */
361 } 403 byte = mpu->read(mpu, MPU401D(mpu));
404 if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode))
405 snd_rawmidi_receive(mpu->substream_input, &byte, 1);
362 } 406 }
363} 407}
364 408
@@ -380,16 +424,16 @@ static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu)
380 int max = 256, timeout; 424 int max = 256, timeout;
381 425
382 do { 426 do {
383 if (snd_rawmidi_transmit_peek(mpu->substream_output, &byte, 1) == 1) { 427 if (snd_rawmidi_transmit_peek(mpu->substream_output,
428 &byte, 1) == 1) {
384 for (timeout = 100; timeout > 0; timeout--) { 429 for (timeout = 100; timeout > 0; timeout--) {
385 if (snd_mpu401_output_ready(mpu)) { 430 if (snd_mpu401_output_ready(mpu))
386 mpu->write(mpu, byte, MPU401D(mpu));
387 snd_rawmidi_transmit_ack(mpu->substream_output, 1);
388 break; 431 break;
389 }
390 } 432 }
391 if (timeout == 0) 433 if (timeout == 0)
392 break; /* Tx FIFO full - try again later */ 434 break; /* Tx FIFO full - try again later */
435 mpu->write(mpu, byte, MPU401D(mpu));
436 snd_rawmidi_transmit_ack(mpu->substream_output, 1);
393 } else { 437 } else {
394 snd_mpu401_uart_remove_timer (mpu, 0); 438 snd_mpu401_uart_remove_timer (mpu, 0);
395 break; /* no other data - leave the tx loop */ 439 break; /* no other data - leave the tx loop */
@@ -400,7 +444,8 @@ static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu)
400/* 444/*
401 * output trigger callback 445 * output trigger callback
402 */ 446 */
403static void snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up) 447static void
448snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up)
404{ 449{
405 unsigned long flags; 450 unsigned long flags;
406 struct snd_mpu401 *mpu; 451 struct snd_mpu401 *mpu;
@@ -413,14 +458,16 @@ static void snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substre
413 * since the output timer might have been removed in 458 * since the output timer might have been removed in
414 * snd_mpu401_uart_output_write(). 459 * snd_mpu401_uart_output_write().
415 */ 460 */
416 snd_mpu401_uart_add_timer(mpu, 0); 461 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
462 snd_mpu401_uart_add_timer(mpu, 0);
417 463
418 /* output pending data */ 464 /* output pending data */
419 spin_lock_irqsave(&mpu->output_lock, flags); 465 spin_lock_irqsave(&mpu->output_lock, flags);
420 snd_mpu401_uart_output_write(mpu); 466 snd_mpu401_uart_output_write(mpu);
421 spin_unlock_irqrestore(&mpu->output_lock, flags); 467 spin_unlock_irqrestore(&mpu->output_lock, flags);
422 } else { 468 } else {
423 snd_mpu401_uart_remove_timer(mpu, 0); 469 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
470 snd_mpu401_uart_remove_timer(mpu, 0);
424 clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); 471 clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode);
425 } 472 }
426} 473}
@@ -458,7 +505,7 @@ static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi)
458 * @device: the device index, zero-based 505 * @device: the device index, zero-based
459 * @hardware: the hardware type, MPU401_HW_XXXX 506 * @hardware: the hardware type, MPU401_HW_XXXX
460 * @port: the base address of MPU401 port 507 * @port: the base address of MPU401 port
461 * @integrated: non-zero if the port was already reserved by the chip 508 * @info_flags: bitflags MPU401_INFO_XXX
462 * @irq: the irq number, -1 if no interrupt for mpu 509 * @irq: the irq number, -1 if no interrupt for mpu
463 * @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved. 510 * @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved.
464 * @rrawmidi: the pointer to store the new rawmidi instance 511 * @rrawmidi: the pointer to store the new rawmidi instance
@@ -473,17 +520,24 @@ static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi)
473 */ 520 */
474int snd_mpu401_uart_new(struct snd_card *card, int device, 521int snd_mpu401_uart_new(struct snd_card *card, int device,
475 unsigned short hardware, 522 unsigned short hardware,
476 unsigned long port, int integrated, 523 unsigned long port,
524 unsigned int info_flags,
477 int irq, int irq_flags, 525 int irq, int irq_flags,
478 struct snd_rawmidi ** rrawmidi) 526 struct snd_rawmidi ** rrawmidi)
479{ 527{
480 struct snd_mpu401 *mpu; 528 struct snd_mpu401 *mpu;
481 struct snd_rawmidi *rmidi; 529 struct snd_rawmidi *rmidi;
530 int in_enable, out_enable;
482 int err; 531 int err;
483 532
484 if (rrawmidi) 533 if (rrawmidi)
485 *rrawmidi = NULL; 534 *rrawmidi = NULL;
486 if ((err = snd_rawmidi_new(card, "MPU-401U", device, 1, 1, &rmidi)) < 0) 535 if (! (info_flags & (MPU401_INFO_INPUT | MPU401_INFO_OUTPUT)))
536 info_flags |= MPU401_INFO_INPUT | MPU401_INFO_OUTPUT;
537 in_enable = (info_flags & MPU401_INFO_INPUT) ? 1 : 0;
538 out_enable = (info_flags & MPU401_INFO_OUTPUT) ? 1 : 0;
539 if ((err = snd_rawmidi_new(card, "MPU-401U", device,
540 out_enable, in_enable, &rmidi)) < 0)
487 return err; 541 return err;
488 mpu = kzalloc(sizeof(*mpu), GFP_KERNEL); 542 mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
489 if (mpu == NULL) { 543 if (mpu == NULL) {
@@ -497,23 +551,23 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
497 spin_lock_init(&mpu->output_lock); 551 spin_lock_init(&mpu->output_lock);
498 spin_lock_init(&mpu->timer_lock); 552 spin_lock_init(&mpu->timer_lock);
499 mpu->hardware = hardware; 553 mpu->hardware = hardware;
500 if (!integrated) { 554 if (! (info_flags & MPU401_INFO_INTEGRATED)) {
501 int res_size = hardware == MPU401_HW_PC98II ? 4 : 2; 555 int res_size = hardware == MPU401_HW_PC98II ? 4 : 2;
502 if ((mpu->res = request_region(port, res_size, "MPU401 UART")) == NULL) { 556 mpu->res = request_region(port, res_size, "MPU401 UART");
503 snd_printk(KERN_ERR "mpu401_uart: unable to grab port 0x%lx size %d\n", port, res_size); 557 if (mpu->res == NULL) {
558 snd_printk(KERN_ERR "mpu401_uart: "
559 "unable to grab port 0x%lx size %d\n",
560 port, res_size);
504 snd_device_free(card, rmidi); 561 snd_device_free(card, rmidi);
505 return -EBUSY; 562 return -EBUSY;
506 } 563 }
507 } 564 }
508 switch (hardware) { 565 if (info_flags & MPU401_INFO_MMIO) {
509 case MPU401_HW_AUREAL:
510 mpu->write = mpu401_write_mmio; 566 mpu->write = mpu401_write_mmio;
511 mpu->read = mpu401_read_mmio; 567 mpu->read = mpu401_read_mmio;
512 break; 568 } else {
513 default:
514 mpu->write = mpu401_write_port; 569 mpu->write = mpu401_write_port;
515 mpu->read = mpu401_read_port; 570 mpu->read = mpu401_read_port;
516 break;
517 } 571 }
518 mpu->port = port; 572 mpu->port = port;
519 if (hardware == MPU401_HW_PC98II) 573 if (hardware == MPU401_HW_PC98II)
@@ -521,30 +575,40 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
521 else 575 else
522 mpu->cport = port + 1; 576 mpu->cport = port + 1;
523 if (irq >= 0 && irq_flags) { 577 if (irq >= 0 && irq_flags) {
524 if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags, "MPU401 UART", (void *) mpu)) { 578 if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags,
525 snd_printk(KERN_ERR "mpu401_uart: unable to grab IRQ %d\n", irq); 579 "MPU401 UART", (void *) mpu)) {
580 snd_printk(KERN_ERR "mpu401_uart: "
581 "unable to grab IRQ %d\n", irq);
526 snd_device_free(card, rmidi); 582 snd_device_free(card, rmidi);
527 return -EBUSY; 583 return -EBUSY;
528 } 584 }
529 } 585 }
586 mpu->info_flags = info_flags;
530 mpu->irq = irq; 587 mpu->irq = irq;
531 mpu->irq_flags = irq_flags; 588 mpu->irq_flags = irq_flags;
532 if (card->shortname[0]) 589 if (card->shortname[0])
533 snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI", card->shortname); 590 snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI",
591 card->shortname);
534 else 592 else
535 sprintf(rmidi->name, "MPU-401 MIDI %d-%d", card->number, device); 593 sprintf(rmidi->name, "MPU-401 MIDI %d-%d",card->number, device);
536 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mpu401_uart_output); 594 if (out_enable) {
537 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mpu401_uart_input); 595 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
538 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | 596 &snd_mpu401_uart_output);
539 SNDRV_RAWMIDI_INFO_INPUT | 597 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
540 SNDRV_RAWMIDI_INFO_DUPLEX; 598 }
599 if (in_enable) {
600 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
601 &snd_mpu401_uart_input);
602 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
603 if (out_enable)
604 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
605 }
541 mpu->rmidi = rmidi; 606 mpu->rmidi = rmidi;
542 if (rrawmidi) 607 if (rrawmidi)
543 *rrawmidi = rmidi; 608 *rrawmidi = rmidi;
544 return 0; 609 return 0;
545} 610}
546 611
547EXPORT_SYMBOL(snd_mpu401_uart_interrupt);
548EXPORT_SYMBOL(snd_mpu401_uart_new); 612EXPORT_SYMBOL(snd_mpu401_uart_new);
549 613
550/* 614/*
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index b7a0b42813e1..474eed06e70f 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -770,11 +770,15 @@ static int __init alsa_card_mtpav_init(void)
770 return err; 770 return err;
771 771
772 device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0); 772 device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0);
773 if (IS_ERR(device)) { 773 if (!IS_ERR(device)) {
774 platform_driver_unregister(&snd_mtpav_driver); 774 if (platform_get_drvdata(device))
775 return PTR_ERR(device); 775 return 0;
776 } 776 platform_device_unregister(device);
777 return 0; 777 err = -ENODEV;
778 } else
779 err = PTR_ERR(device);
780 platform_driver_unregister(&snd_mtpav_driver);
781 return err;
778} 782}
779 783
780static void __exit alsa_card_mtpav_exit(void) 784static void __exit alsa_card_mtpav_exit(void)
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index 4f8556976774..87fe376f38f0 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -316,6 +316,8 @@ void snd_opl3_interrupt(struct snd_hwdep * hw)
316 } 316 }
317} 317}
318 318
319EXPORT_SYMBOL(snd_opl3_interrupt);
320
319/* 321/*
320 322
321 */ 323 */
@@ -369,6 +371,8 @@ int snd_opl3_new(struct snd_card *card,
369 return 0; 371 return 0;
370} 372}
371 373
374EXPORT_SYMBOL(snd_opl3_new);
375
372int snd_opl3_init(struct snd_opl3 *opl3) 376int snd_opl3_init(struct snd_opl3 *opl3)
373{ 377{
374 if (! opl3->command) { 378 if (! opl3->command) {
@@ -393,6 +397,8 @@ int snd_opl3_init(struct snd_opl3 *opl3)
393 return 0; 397 return 0;
394} 398}
395 399
400EXPORT_SYMBOL(snd_opl3_init);
401
396int snd_opl3_create(struct snd_card *card, 402int snd_opl3_create(struct snd_card *card,
397 unsigned long l_port, 403 unsigned long l_port,
398 unsigned long r_port, 404 unsigned long r_port,
@@ -451,6 +457,8 @@ int snd_opl3_create(struct snd_card *card,
451 return 0; 457 return 0;
452} 458}
453 459
460EXPORT_SYMBOL(snd_opl3_create);
461
454int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev) 462int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
455{ 463{
456 int err; 464 int err;
@@ -468,6 +476,8 @@ int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
468 return 0; 476 return 0;
469} 477}
470 478
479EXPORT_SYMBOL(snd_opl3_timer_new);
480
471int snd_opl3_hwdep_new(struct snd_opl3 * opl3, 481int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
472 int device, int seq_device, 482 int device, int seq_device,
473 struct snd_hwdep ** rhwdep) 483 struct snd_hwdep ** rhwdep)
@@ -526,17 +536,8 @@ int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
526 return 0; 536 return 0;
527} 537}
528 538
529EXPORT_SYMBOL(snd_opl3_interrupt);
530EXPORT_SYMBOL(snd_opl3_new);
531EXPORT_SYMBOL(snd_opl3_init);
532EXPORT_SYMBOL(snd_opl3_create);
533EXPORT_SYMBOL(snd_opl3_timer_new);
534EXPORT_SYMBOL(snd_opl3_hwdep_new); 539EXPORT_SYMBOL(snd_opl3_hwdep_new);
535 540
536/* opl3_synth.c */
537EXPORT_SYMBOL(snd_opl3_regmap);
538EXPORT_SYMBOL(snd_opl3_reset);
539
540/* 541/*
541 * INIT part 542 * INIT part
542 */ 543 */
diff --git a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c
index fccf019a6d85..5fd3a4c95626 100644
--- a/sound/drivers/opl3/opl3_oss.c
+++ b/sound/drivers/opl3/opl3_oss.c
@@ -100,7 +100,8 @@ static int snd_opl3_oss_create_port(struct snd_opl3 * opl3)
100 SNDRV_SEQ_PORT_CAP_WRITE, 100 SNDRV_SEQ_PORT_CAP_WRITE,
101 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | 101 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
102 SNDRV_SEQ_PORT_TYPE_MIDI_GM | 102 SNDRV_SEQ_PORT_TYPE_MIDI_GM |
103 SNDRV_SEQ_PORT_TYPE_SYNTH, 103 SNDRV_SEQ_PORT_TYPE_HARDWARE |
104 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
104 voices, voices, 105 voices, voices,
105 name); 106 name);
106 if (opl3->oss_chset->port < 0) { 107 if (opl3->oss_chset->port < 0) {
diff --git a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c
index 57becf34f43e..96762c9d4855 100644
--- a/sound/drivers/opl3/opl3_seq.c
+++ b/sound/drivers/opl3/opl3_seq.c
@@ -203,7 +203,9 @@ static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
203 SNDRV_SEQ_PORT_CAP_SUBS_WRITE, 203 SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
204 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | 204 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
205 SNDRV_SEQ_PORT_TYPE_MIDI_GM | 205 SNDRV_SEQ_PORT_TYPE_MIDI_GM |
206 SNDRV_SEQ_PORT_TYPE_SYNTH, 206 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
207 SNDRV_SEQ_PORT_TYPE_HARDWARE |
208 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
207 16, voices, 209 16, voices,
208 name); 210 name);
209 if (opl3->chset->port < 0) { 211 if (opl3->chset->port < 0) {
diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c
index 6db503f025b3..a4b3543a7118 100644
--- a/sound/drivers/opl3/opl3_synth.c
+++ b/sound/drivers/opl3/opl3_synth.c
@@ -58,6 +58,8 @@ char snd_opl3_regmap[MAX_OPL2_VOICES][4] =
58 { 0x12, 0x15, 0x00, 0x00 } /* is selected (only left reg block) */ 58 { 0x12, 0x15, 0x00, 0x00 } /* is selected (only left reg block) */
59}; 59};
60 60
61EXPORT_SYMBOL(snd_opl3_regmap);
62
61/* 63/*
62 * prototypes 64 * prototypes
63 */ 65 */
@@ -228,6 +230,7 @@ void snd_opl3_reset(struct snd_opl3 * opl3)
228 opl3->rhythm = 0; 230 opl3->rhythm = 0;
229} 231}
230 232
233EXPORT_SYMBOL(snd_opl3_reset);
231 234
232static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note) 235static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note)
233{ 236{
@@ -445,3 +448,4 @@ static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection)
445 448
446 return 0; 449 return 0;
447} 450}
451
diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c
index 4bc860ae02de..01997f24c895 100644
--- a/sound/drivers/opl4/opl4_lib.c
+++ b/sound/drivers/opl4/opl4_lib.c
@@ -43,6 +43,8 @@ void snd_opl4_write(struct snd_opl4 *opl4, u8 reg, u8 value)
43 outb(value, opl4->pcm_port + 1); 43 outb(value, opl4->pcm_port + 1);
44} 44}
45 45
46EXPORT_SYMBOL(snd_opl4_write);
47
46u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg) 48u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg)
47{ 49{
48 snd_opl4_wait(opl4); 50 snd_opl4_wait(opl4);
@@ -52,6 +54,8 @@ u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg)
52 return inb(opl4->pcm_port + 1); 54 return inb(opl4->pcm_port + 1);
53} 55}
54 56
57EXPORT_SYMBOL(snd_opl4_read);
58
55void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size) 59void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size)
56{ 60{
57 unsigned long flags; 61 unsigned long flags;
@@ -76,6 +80,8 @@ void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size
76 spin_unlock_irqrestore(&opl4->reg_lock, flags); 80 spin_unlock_irqrestore(&opl4->reg_lock, flags);
77} 81}
78 82
83EXPORT_SYMBOL(snd_opl4_read_memory);
84
79void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size) 85void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size)
80{ 86{
81 unsigned long flags; 87 unsigned long flags;
@@ -100,6 +106,8 @@ void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, i
100 spin_unlock_irqrestore(&opl4->reg_lock, flags); 106 spin_unlock_irqrestore(&opl4->reg_lock, flags);
101} 107}
102 108
109EXPORT_SYMBOL(snd_opl4_write_memory);
110
103static void snd_opl4_enable_opl4(struct snd_opl4 *opl4) 111static void snd_opl4_enable_opl4(struct snd_opl4 *opl4)
104{ 112{
105 outb(OPL3_REG_MODE, opl4->fm_port + 2); 113 outb(OPL3_REG_MODE, opl4->fm_port + 2);
@@ -256,10 +264,6 @@ int snd_opl4_create(struct snd_card *card,
256 return 0; 264 return 0;
257} 265}
258 266
259EXPORT_SYMBOL(snd_opl4_write);
260EXPORT_SYMBOL(snd_opl4_read);
261EXPORT_SYMBOL(snd_opl4_write_memory);
262EXPORT_SYMBOL(snd_opl4_read_memory);
263EXPORT_SYMBOL(snd_opl4_create); 267EXPORT_SYMBOL(snd_opl4_create);
264 268
265static int __init alsa_opl4_init(void) 269static int __init alsa_opl4_init(void)
diff --git a/sound/drivers/opl4/opl4_seq.c b/sound/drivers/opl4/opl4_seq.c
index dc0dcdc6c313..43d8a2bdd280 100644
--- a/sound/drivers/opl4/opl4_seq.c
+++ b/sound/drivers/opl4/opl4_seq.c
@@ -164,7 +164,9 @@ static int snd_opl4_seq_new_device(struct snd_seq_device *dev)
164 SNDRV_SEQ_PORT_CAP_WRITE | 164 SNDRV_SEQ_PORT_CAP_WRITE |
165 SNDRV_SEQ_PORT_CAP_SUBS_WRITE, 165 SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
166 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | 166 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
167 SNDRV_SEQ_PORT_TYPE_MIDI_GM, 167 SNDRV_SEQ_PORT_TYPE_MIDI_GM |
168 SNDRV_SEQ_PORT_TYPE_HARDWARE |
169 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
168 16, 24, 170 16, 24,
169 "OPL4 Wavetable Port"); 171 "OPL4 Wavetable Port");
170 if (opl4->chset->port < 0) { 172 if (opl4->chset->port < 0) {
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index c01b4c5118b9..2330fec505da 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -998,6 +998,10 @@ static int __init alsa_card_serial_init(void)
998 i, NULL, 0); 998 i, NULL, 0);
999 if (IS_ERR(device)) 999 if (IS_ERR(device))
1000 continue; 1000 continue;
1001 if (!platform_get_drvdata(device)) {
1002 platform_device_unregister(device);
1003 continue;
1004 }
1001 devices[i] = device; 1005 devices[i] = device;
1002 cards++; 1006 cards++;
1003 } 1007 }
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index 26eb2499d442..59171f8200df 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -171,6 +171,10 @@ static int __init alsa_card_virmidi_init(void)
171 i, NULL, 0); 171 i, NULL, 0);
172 if (IS_ERR(device)) 172 if (IS_ERR(device))
173 continue; 173 continue;
174 if (!platform_get_drvdata(device)) {
175 platform_device_unregister(device);
176 continue;
177 }
174 devices[i] = device; 178 devices[i] = device;
175 cards++; 179 cards++;
176 } 180 }
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index fa4a2b5c2d8d..a60168268ddd 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -70,6 +70,8 @@ int snd_vx_check_reg_bit(struct vx_core *chip, int reg, int mask, int bit, int t
70 return -EIO; 70 return -EIO;
71} 71}
72 72
73EXPORT_SYMBOL(snd_vx_check_reg_bit);
74
73/* 75/*
74 * vx_send_irq_dsp - set command irq bit 76 * vx_send_irq_dsp - set command irq bit
75 * @num: the requested IRQ type, IRQ_XXX 77 * @num: the requested IRQ type, IRQ_XXX
@@ -465,6 +467,8 @@ int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot)
465 return 0; 467 return 0;
466} 468}
467 469
470EXPORT_SYMBOL(snd_vx_load_boot_image);
471
468/* 472/*
469 * vx_test_irq_src - query the source of interrupts 473 * vx_test_irq_src - query the source of interrupts
470 * 474 *
@@ -545,6 +549,7 @@ irqreturn_t snd_vx_irq_handler(int irq, void *dev, struct pt_regs *regs)
545 return IRQ_HANDLED; 549 return IRQ_HANDLED;
546} 550}
547 551
552EXPORT_SYMBOL(snd_vx_irq_handler);
548 553
549/* 554/*
550 */ 555 */
@@ -635,7 +640,7 @@ static void vx_proc_init(struct vx_core *chip)
635 struct snd_info_entry *entry; 640 struct snd_info_entry *entry;
636 641
637 if (! snd_card_proc_new(chip->card, "vx-status", &entry)) 642 if (! snd_card_proc_new(chip->card, "vx-status", &entry))
638 snd_info_set_text_ops(entry, chip, 1024, vx_proc_read); 643 snd_info_set_text_ops(entry, chip, vx_proc_read);
639} 644}
640 645
641 646
@@ -657,6 +662,8 @@ int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *boot)
657 return 0; 662 return 0;
658} 663}
659 664
665EXPORT_SYMBOL(snd_vx_dsp_boot);
666
660/** 667/**
661 * snd_vx_dsp_load - load the DSP image 668 * snd_vx_dsp_load - load the DSP image
662 */ 669 */
@@ -705,6 +712,8 @@ int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp)
705 return 0; 712 return 0;
706} 713}
707 714
715EXPORT_SYMBOL(snd_vx_dsp_load);
716
708#ifdef CONFIG_PM 717#ifdef CONFIG_PM
709/* 718/*
710 * suspend 719 * suspend
@@ -721,6 +730,8 @@ int snd_vx_suspend(struct vx_core *chip, pm_message_t state)
721 return 0; 730 return 0;
722} 731}
723 732
733EXPORT_SYMBOL(snd_vx_suspend);
734
724/* 735/*
725 * resume 736 * resume
726 */ 737 */
@@ -747,6 +758,7 @@ int snd_vx_resume(struct vx_core *chip)
747 return 0; 758 return 0;
748} 759}
749 760
761EXPORT_SYMBOL(snd_vx_resume);
750#endif 762#endif
751 763
752/** 764/**
@@ -790,6 +802,8 @@ struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
790 return chip; 802 return chip;
791} 803}
792 804
805EXPORT_SYMBOL(snd_vx_create);
806
793/* 807/*
794 * module entries 808 * module entries
795 */ 809 */
@@ -804,19 +818,3 @@ static void __exit alsa_vx_core_exit(void)
804 818
805module_init(alsa_vx_core_init) 819module_init(alsa_vx_core_init)
806module_exit(alsa_vx_core_exit) 820module_exit(alsa_vx_core_exit)
807
808/*
809 * exports
810 */
811EXPORT_SYMBOL(snd_vx_check_reg_bit);
812EXPORT_SYMBOL(snd_vx_create);
813EXPORT_SYMBOL(snd_vx_setup_firmware);
814EXPORT_SYMBOL(snd_vx_free_firmware);
815EXPORT_SYMBOL(snd_vx_irq_handler);
816EXPORT_SYMBOL(snd_vx_dsp_boot);
817EXPORT_SYMBOL(snd_vx_dsp_load);
818EXPORT_SYMBOL(snd_vx_load_boot_image);
819#ifdef CONFIG_PM
820EXPORT_SYMBOL(snd_vx_suspend);
821EXPORT_SYMBOL(snd_vx_resume);
822#endif
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index d837783fb538..e1920af4501d 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -250,3 +250,6 @@ void snd_vx_free_firmware(struct vx_core *chip)
250} 250}
251 251
252#endif /* SND_VX_FW_LOADER */ 252#endif /* SND_VX_FW_LOADER */
253
254EXPORT_SYMBOL(snd_vx_setup_firmware);
255EXPORT_SYMBOL(snd_vx_free_firmware);
diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c
index edfe76fb0074..b60fb1892828 100644
--- a/sound/i2c/i2c.c
+++ b/sound/i2c/i2c.c
@@ -106,6 +106,8 @@ int snd_i2c_bus_create(struct snd_card *card, const char *name,
106 return 0; 106 return 0;
107} 107}
108 108
109EXPORT_SYMBOL(snd_i2c_bus_create);
110
109int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name, 111int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name,
110 unsigned char addr, struct snd_i2c_device **rdevice) 112 unsigned char addr, struct snd_i2c_device **rdevice)
111{ 113{
@@ -124,6 +126,8 @@ int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name,
124 return 0; 126 return 0;
125} 127}
126 128
129EXPORT_SYMBOL(snd_i2c_device_create);
130
127int snd_i2c_device_free(struct snd_i2c_device *device) 131int snd_i2c_device_free(struct snd_i2c_device *device)
128{ 132{
129 if (device->bus) 133 if (device->bus)
@@ -134,22 +138,29 @@ int snd_i2c_device_free(struct snd_i2c_device *device)
134 return 0; 138 return 0;
135} 139}
136 140
141EXPORT_SYMBOL(snd_i2c_device_free);
142
137int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count) 143int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
138{ 144{
139 return device->bus->ops->sendbytes(device, bytes, count); 145 return device->bus->ops->sendbytes(device, bytes, count);
140} 146}
141 147
148EXPORT_SYMBOL(snd_i2c_sendbytes);
142 149
143int snd_i2c_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count) 150int snd_i2c_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
144{ 151{
145 return device->bus->ops->readbytes(device, bytes, count); 152 return device->bus->ops->readbytes(device, bytes, count);
146} 153}
147 154
155EXPORT_SYMBOL(snd_i2c_readbytes);
156
148int snd_i2c_probeaddr(struct snd_i2c_bus *bus, unsigned short addr) 157int snd_i2c_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
149{ 158{
150 return bus->ops->probeaddr(bus, addr); 159 return bus->ops->probeaddr(bus, addr);
151} 160}
152 161
162EXPORT_SYMBOL(snd_i2c_probeaddr);
163
153/* 164/*
154 * bit-operations 165 * bit-operations
155 */ 166 */
@@ -320,12 +331,6 @@ static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
320 return err; 331 return err;
321} 332}
322 333
323EXPORT_SYMBOL(snd_i2c_bus_create);
324EXPORT_SYMBOL(snd_i2c_device_create);
325EXPORT_SYMBOL(snd_i2c_device_free);
326EXPORT_SYMBOL(snd_i2c_sendbytes);
327EXPORT_SYMBOL(snd_i2c_readbytes);
328EXPORT_SYMBOL(snd_i2c_probeaddr);
329 334
330static int __init alsa_i2c_init(void) 335static int __init alsa_i2c_init(void)
331{ 336{
diff --git a/sound/i2c/l3/uda1341.c b/sound/i2c/l3/uda1341.c
index 746500e06950..b074fdddea55 100644
--- a/sound/i2c/l3/uda1341.c
+++ b/sound/i2c/l3/uda1341.c
@@ -517,9 +517,9 @@ static void __devinit snd_uda1341_proc_init(struct snd_card *card, struct l3_cli
517 struct snd_info_entry *entry; 517 struct snd_info_entry *entry;
518 518
519 if (! snd_card_proc_new(card, "uda1341", &entry)) 519 if (! snd_card_proc_new(card, "uda1341", &entry))
520 snd_info_set_text_ops(entry, clnt, 1024, snd_uda1341_proc_read); 520 snd_info_set_text_ops(entry, clnt, snd_uda1341_proc_read);
521 if (! snd_card_proc_new(card, "uda1341-regs", &entry)) 521 if (! snd_card_proc_new(card, "uda1341-regs", &entry))
522 snd_info_set_text_ops(entry, clnt, 1024, snd_uda1341_proc_regs_read); 522 snd_info_set_text_ops(entry, clnt, snd_uda1341_proc_regs_read);
523} 523}
524 524
525/* }}} */ 525/* }}} */
diff --git a/sound/isa/gus/gus_irq.c b/sound/isa/gus/gus_irq.c
index c19ba2910b72..42db37552efb 100644
--- a/sound/isa/gus/gus_irq.c
+++ b/sound/isa/gus/gus_irq.c
@@ -136,7 +136,7 @@ void snd_gus_irq_profile_init(struct snd_gus_card *gus)
136 struct snd_info_entry *entry; 136 struct snd_info_entry *entry;
137 137
138 if (! snd_card_proc_new(gus->card, "gusirq", &entry)) 138 if (! snd_card_proc_new(gus->card, "gusirq", &entry))
139 snd_info_set_text_ops(entry, gus, 1024, snd_gus_irq_info_read); 139 snd_info_set_text_ops(entry, gus, snd_gus_irq_info_read);
140} 140}
141 141
142#endif 142#endif
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
index 3c0d27aa08b3..f50c276caee8 100644
--- a/sound/isa/gus/gus_mem.c
+++ b/sound/isa/gus/gus_mem.c
@@ -264,10 +264,8 @@ int snd_gf1_mem_init(struct snd_gus_card * gus)
264 if (snd_gf1_mem_xalloc(alloc, &block) == NULL) 264 if (snd_gf1_mem_xalloc(alloc, &block) == NULL)
265 return -ENOMEM; 265 return -ENOMEM;
266#ifdef CONFIG_SND_DEBUG 266#ifdef CONFIG_SND_DEBUG
267 if (! snd_card_proc_new(gus->card, "gusmem", &entry)) { 267 if (! snd_card_proc_new(gus->card, "gusmem", &entry))
268 snd_info_set_text_ops(entry, gus, 1024, snd_gf1_mem_info_read); 268 snd_info_set_text_ops(entry, gus, snd_gf1_mem_info_read);
269 entry->c.text.read_size = 256 * 1024;
270 }
271#endif 269#endif
272 return 0; 270 return 0;
273} 271}
diff --git a/sound/isa/gus/gus_synth.c b/sound/isa/gus/gus_synth.c
index 2767cc187ae3..3e4d4d6edd8b 100644
--- a/sound/isa/gus/gus_synth.c
+++ b/sound/isa/gus/gus_synth.c
@@ -194,7 +194,9 @@ static int snd_gus_synth_create_port(struct snd_gus_card * gus, int idx)
194 &callbacks, 194 &callbacks,
195 SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE, 195 SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
196 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE | 196 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
197 SNDRV_SEQ_PORT_TYPE_SYNTH, 197 SNDRV_SEQ_PORT_TYPE_SYNTH |
198 SNDRV_SEQ_PORT_TYPE_HARDWARE |
199 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
198 16, 0, 200 16, 0,
199 name); 201 name);
200 if (p->chset->port < 0) { 202 if (p->chset->port < 0) {
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 4298d339e786..866300f2acbb 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -70,9 +70,9 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
70static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ 70static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
71static int joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29}; 71static int joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29};
72 /* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */ 72 /* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */
73static int midi[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 73static int midi[SNDRV_CARDS];
74static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; 74static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
75static int effect[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 75static int effect[SNDRV_CARDS];
76 76
77#ifdef SNDRV_STB 77#ifdef SNDRV_STB
78#define PFX "interwave-stb: " 78#define PFX "interwave-stb: "
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 6d889052c32c..647a996791e9 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -59,7 +59,7 @@ static long midi_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;/* 0x330,0x300 */
59static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 0,1,3,5,9,11,12,15 */ 59static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 0,1,3,5,9,11,12,15 */
60static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */ 60static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */
61static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */ 61static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */
62static int opl3sa3_ymode[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* 0,1,2,3 */ /*SL Added*/ 62static int opl3sa3_ymode[SNDRV_CARDS]; /* 0,1,2,3 */ /*SL Added*/
63 63
64module_param_array(index, int, NULL, 0444); 64module_param_array(index, int, NULL, 0444);
65MODULE_PARM_DESC(index, "Index value for OPL3-SA soundcard."); 65MODULE_PARM_DESC(index, "Index value for OPL3-SA soundcard.");
@@ -221,7 +221,7 @@ static void snd_opl3sa2_write(struct snd_opl3sa2 *chip, unsigned char reg, unsig
221 spin_unlock_irqrestore(&chip->reg_lock, flags); 221 spin_unlock_irqrestore(&chip->reg_lock, flags);
222} 222}
223 223
224static int __init snd_opl3sa2_detect(struct snd_opl3sa2 *chip) 224static int __devinit snd_opl3sa2_detect(struct snd_opl3sa2 *chip)
225{ 225{
226 struct snd_card *card; 226 struct snd_card *card;
227 unsigned long port; 227 unsigned long port;
@@ -489,7 +489,7 @@ static void snd_opl3sa2_master_free(struct snd_kcontrol *kcontrol)
489 chip->master_volume = NULL; 489 chip->master_volume = NULL;
490} 490}
491 491
492static int __init snd_opl3sa2_mixer(struct snd_opl3sa2 *chip) 492static int __devinit snd_opl3sa2_mixer(struct snd_opl3sa2 *chip)
493{ 493{
494 struct snd_card *card = chip->card; 494 struct snd_card *card = chip->card;
495 struct snd_ctl_elem_id id1, id2; 495 struct snd_ctl_elem_id id1, id2;
@@ -583,8 +583,8 @@ static int snd_opl3sa2_resume(struct snd_card *card)
583#endif /* CONFIG_PM */ 583#endif /* CONFIG_PM */
584 584
585#ifdef CONFIG_PNP 585#ifdef CONFIG_PNP
586static int __init snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip, 586static int __devinit snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip,
587 struct pnp_dev *pdev) 587 struct pnp_dev *pdev)
588{ 588{
589 struct pnp_resource_table * cfg; 589 struct pnp_resource_table * cfg;
590 int err; 590 int err;
@@ -862,7 +862,7 @@ static struct pnp_card_driver opl3sa2_pnpc_driver = {
862}; 862};
863#endif /* CONFIG_PNP */ 863#endif /* CONFIG_PNP */
864 864
865static int __init snd_opl3sa2_nonpnp_probe(struct platform_device *pdev) 865static int __devinit snd_opl3sa2_nonpnp_probe(struct platform_device *pdev)
866{ 866{
867 struct snd_card *card; 867 struct snd_card *card;
868 int err; 868 int err;
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index e6bfcf74c1c1..283817f2de75 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -967,7 +967,7 @@ static void __init snd_miro_proc_init(struct snd_miro * miro)
967 struct snd_info_entry *entry; 967 struct snd_info_entry *entry;
968 968
969 if (! snd_card_proc_new(miro->card, "miro", &entry)) 969 if (! snd_card_proc_new(miro->card, "miro", &entry))
970 snd_info_set_text_ops(entry, miro, 1024, snd_miro_proc_read); 970 snd_info_set_text_ops(entry, miro, snd_miro_proc_read);
971} 971}
972 972
973/* 973/*
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index c0b8d61b75e7..658179e86142 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -131,7 +131,7 @@ snd_emu8000_dma_chan(struct snd_emu8000 *emu, int ch, int mode)
131 131
132/* 132/*
133 */ 133 */
134static void __init 134static void __devinit
135snd_emu8000_read_wait(struct snd_emu8000 *emu) 135snd_emu8000_read_wait(struct snd_emu8000 *emu)
136{ 136{
137 while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) { 137 while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) {
@@ -143,7 +143,7 @@ snd_emu8000_read_wait(struct snd_emu8000 *emu)
143 143
144/* 144/*
145 */ 145 */
146static void __init 146static void __devinit
147snd_emu8000_write_wait(struct snd_emu8000 *emu) 147snd_emu8000_write_wait(struct snd_emu8000 *emu)
148{ 148{
149 while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) { 149 while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
@@ -156,7 +156,7 @@ snd_emu8000_write_wait(struct snd_emu8000 *emu)
156/* 156/*
157 * detect a card at the given port 157 * detect a card at the given port
158 */ 158 */
159static int __init 159static int __devinit
160snd_emu8000_detect(struct snd_emu8000 *emu) 160snd_emu8000_detect(struct snd_emu8000 *emu)
161{ 161{
162 /* Initialise */ 162 /* Initialise */
@@ -182,7 +182,7 @@ snd_emu8000_detect(struct snd_emu8000 *emu)
182/* 182/*
183 * intiailize audio channels 183 * intiailize audio channels
184 */ 184 */
185static void __init 185static void __devinit
186init_audio(struct snd_emu8000 *emu) 186init_audio(struct snd_emu8000 *emu)
187{ 187{
188 int ch; 188 int ch;
@@ -223,7 +223,7 @@ init_audio(struct snd_emu8000 *emu)
223/* 223/*
224 * initialize DMA address 224 * initialize DMA address
225 */ 225 */
226static void __init 226static void __devinit
227init_dma(struct snd_emu8000 *emu) 227init_dma(struct snd_emu8000 *emu)
228{ 228{
229 EMU8000_SMALR_WRITE(emu, 0); 229 EMU8000_SMALR_WRITE(emu, 0);
@@ -327,7 +327,7 @@ static unsigned short init4[128] /*__devinitdata*/ = {
327 * Taken from the oss driver, not obvious from the doc how this 327 * Taken from the oss driver, not obvious from the doc how this
328 * is meant to work 328 * is meant to work
329 */ 329 */
330static void __init 330static void __devinit
331send_array(struct snd_emu8000 *emu, unsigned short *data, int size) 331send_array(struct snd_emu8000 *emu, unsigned short *data, int size)
332{ 332{
333 int i; 333 int i;
@@ -349,7 +349,7 @@ send_array(struct snd_emu8000 *emu, unsigned short *data, int size)
349 * Send initialization arrays to start up, this just follows the 349 * Send initialization arrays to start up, this just follows the
350 * initialisation sequence in the adip. 350 * initialisation sequence in the adip.
351 */ 351 */
352static void __init 352static void __devinit
353init_arrays(struct snd_emu8000 *emu) 353init_arrays(struct snd_emu8000 *emu)
354{ 354{
355 send_array(emu, init1, ARRAY_SIZE(init1)/4); 355 send_array(emu, init1, ARRAY_SIZE(init1)/4);
@@ -375,7 +375,7 @@ init_arrays(struct snd_emu8000 *emu)
375 * seems that the only way to do this is to use the one channel and keep 375 * seems that the only way to do this is to use the one channel and keep
376 * reallocating between read and write. 376 * reallocating between read and write.
377 */ 377 */
378static void __init 378static void __devinit
379size_dram(struct snd_emu8000 *emu) 379size_dram(struct snd_emu8000 *emu)
380{ 380{
381 int i, size; 381 int i, size;
@@ -500,7 +500,7 @@ snd_emu8000_init_fm(struct snd_emu8000 *emu)
500/* 500/*
501 * The main initialization routine. 501 * The main initialization routine.
502 */ 502 */
503static void __init 503static void __devinit
504snd_emu8000_init_hw(struct snd_emu8000 *emu) 504snd_emu8000_init_hw(struct snd_emu8000 *emu)
505{ 505{
506 int i; 506 int i;
@@ -1019,7 +1019,7 @@ static struct snd_kcontrol_new *mixer_defs[EMU8000_NUM_CONTROLS] = {
1019/* 1019/*
1020 * create and attach mixer elements for WaveTable treble/bass controls 1020 * create and attach mixer elements for WaveTable treble/bass controls
1021 */ 1021 */
1022static int __init 1022static int __devinit
1023snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu) 1023snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
1024{ 1024{
1025 int i, err = 0; 1025 int i, err = 0;
@@ -1069,7 +1069,7 @@ static int snd_emu8000_dev_free(struct snd_device *device)
1069/* 1069/*
1070 * initialize and register emu8000 synth device. 1070 * initialize and register emu8000 synth device.
1071 */ 1071 */
1072int __init 1072int __devinit
1073snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports, 1073snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
1074 struct snd_seq_device **awe_ret) 1074 struct snd_seq_device **awe_ret)
1075{ 1075{
diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c
index 80b1cf84a1ae..1be16c9700f0 100644
--- a/sound/isa/sb/emu8000_patch.c
+++ b/sound/isa/sb/emu8000_patch.c
@@ -23,7 +23,7 @@
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
25 25
26static int emu8000_reset_addr = 0; 26static int emu8000_reset_addr;
27module_param(emu8000_reset_addr, int, 0444); 27module_param(emu8000_reset_addr, int, 0444);
28MODULE_PARM_DESC(emu8000_reset_addr, "reset write address at each time (makes slowdown)"); 28MODULE_PARM_DESC(emu8000_reset_addr, "reset write address at each time (makes slowdown)");
29 29
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 6333f900eaee..7f7f05fa518a 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -85,7 +85,7 @@ static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */
85static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 5,6,7 */ 85static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 5,6,7 */
86static int mic_agc[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; 86static int mic_agc[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
87#ifdef CONFIG_SND_SB16_CSP 87#ifdef CONFIG_SND_SB16_CSP
88static int csp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 88static int csp[SNDRV_CARDS];
89#endif 89#endif
90#ifdef SNDRV_SBAWE_EMU8000 90#ifdef SNDRV_SBAWE_EMU8000
91static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4}; 91static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4};
diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c
index 9703c68e4e08..fcd638090a9e 100644
--- a/sound/isa/sb/sb16_csp.c
+++ b/sound/isa/sb/sb16_csp.c
@@ -1101,7 +1101,7 @@ static int init_proc_entry(struct snd_sb_csp * p, int device)
1101 struct snd_info_entry *entry; 1101 struct snd_info_entry *entry;
1102 sprintf(name, "cspD%d", device); 1102 sprintf(name, "cspD%d", device);
1103 if (! snd_card_proc_new(p->chip->card, name, &entry)) 1103 if (! snd_card_proc_new(p->chip->card, name, &entry))
1104 snd_info_set_text_ops(entry, p, 1024, info_read); 1104 snd_info_set_text_ops(entry, p, info_read);
1105 return 0; 1105 return 0;
1106} 1106}
1107 1107
diff --git a/sound/isa/sb/sb8_midi.c b/sound/isa/sb/sb8_midi.c
index c549aceea294..0b67edd7ac6e 100644
--- a/sound/isa/sb/sb8_midi.c
+++ b/sound/isa/sb/sb8_midi.c
@@ -32,20 +32,22 @@
32#include <sound/core.h> 32#include <sound/core.h>
33#include <sound/sb.h> 33#include <sound/sb.h>
34 34
35/*
36
37 */
38 35
39irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb * chip) 36irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb *chip)
40{ 37{
41 struct snd_rawmidi *rmidi; 38 struct snd_rawmidi *rmidi;
42 int max = 64; 39 int max = 64;
43 char byte; 40 char byte;
44 41
45 if (chip == NULL || (rmidi = chip->rmidi) == NULL) { 42 if (!chip)
43 return IRQ_NONE;
44
45 rmidi = chip->rmidi;
46 if (!rmidi) {
46 inb(SBP(chip, DATA_AVAIL)); /* ack interrupt */ 47 inb(SBP(chip, DATA_AVAIL)); /* ack interrupt */
47 return IRQ_NONE; 48 return IRQ_NONE;
48 } 49 }
50
49 spin_lock(&chip->midi_input_lock); 51 spin_lock(&chip->midi_input_lock);
50 while (max-- > 0) { 52 while (max-- > 0) {
51 if (inb(SBP(chip, DATA_AVAIL)) & 0x80) { 53 if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
@@ -59,10 +61,6 @@ irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb * chip)
59 return IRQ_HANDLED; 61 return IRQ_HANDLED;
60} 62}
61 63
62/*
63
64 */
65
66static int snd_sb8dsp_midi_input_open(struct snd_rawmidi_substream *substream) 64static int snd_sb8dsp_midi_input_open(struct snd_rawmidi_substream *substream)
67{ 65{
68 unsigned long flags; 66 unsigned long flags;
@@ -252,10 +250,6 @@ static void snd_sb8dsp_midi_output_trigger(struct snd_rawmidi_substream *substre
252 snd_sb8dsp_midi_output_write(substream); 250 snd_sb8dsp_midi_output_write(substream);
253} 251}
254 252
255/*
256
257 */
258
259static struct snd_rawmidi_ops snd_sb8dsp_midi_output = 253static struct snd_rawmidi_ops snd_sb8dsp_midi_output =
260{ 254{
261 .open = snd_sb8dsp_midi_output_open, 255 .open = snd_sb8dsp_midi_output_open,
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index d2a856f0fde2..27271c9446dc 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -897,10 +897,9 @@ static int __devinit create_mpu401(struct snd_card *card, int devnum, unsigned l
897 struct snd_rawmidi *rawmidi; 897 struct snd_rawmidi *rawmidi;
898 int err; 898 int err;
899 899
900#define MPU401_SHARE_HARDWARE 1
901 if ((err = snd_mpu401_uart_new(card, devnum, 900 if ((err = snd_mpu401_uart_new(card, devnum,
902 MPU401_HW_MPU401, 901 MPU401_HW_MPU401,
903 port, MPU401_SHARE_HARDWARE, 902 port, MPU401_INFO_INTEGRATED,
904 irq, SA_INTERRUPT, 903 irq, SA_INTERRUPT,
905 &rawmidi)) == 0) { 904 &rawmidi)) == 0) {
906 struct snd_mpu401 *mpu = (struct snd_mpu401 *) rawmidi->private_data; 905 struct snd_mpu401 *mpu = (struct snd_mpu401 *) rawmidi->private_data;
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 7ae86f82c3fa..9eb27082c659 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -50,7 +50,7 @@ static int ics2115_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 2,9,11,12,15 */
50static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ 50static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
51static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ 51static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
52static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ 52static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
53static int use_cs4232_midi[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 53static int use_cs4232_midi[SNDRV_CARDS];
54 54
55module_param_array(index, int, NULL, 0444); 55module_param_array(index, int, NULL, 0444);
56MODULE_PARM_DESC(index, "Index value for WaveFront soundcard."); 56MODULE_PARM_DESC(index, "Index value for WaveFront soundcard.");
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index a2081803a827..d37346b12dc0 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -216,14 +216,19 @@ config SND_CS46XX_NEW_DSP
216 This works better than the old code, so say Y. 216 This works better than the old code, so say Y.
217 217
218config SND_CS5535AUDIO 218config SND_CS5535AUDIO
219 tristate "CS5535 Audio" 219 tristate "CS5535/CS5536 Audio"
220 depends on SND && X86 && !X86_64 220 depends on SND && X86 && !X86_64
221 select SND_PCM 221 select SND_PCM
222 select SND_AC97_CODEC 222 select SND_AC97_CODEC
223 help 223 help
224 Say Y here to include support for audio on CS5535 chips. It is 224 Say Y here to include support for audio on CS5535 chips. It is
225 referred to as NS CS5535 IO or AMD CS5535 IO companion in 225 referred to as NS CS5535 IO or AMD CS5535 IO companion in
226 various literature. 226 various literature. This driver also supports the CS5536 audio
227 device. However, for both chips, on certain boards, you may
228 need to use ac97_quirk=hp_only if your board has physically
229 mapped headphone out to master output. If that works for you,
230 send lspci -vvv output to the mailing list so that your board
231 can be identified in the quirks list.
227 232
228 To compile this driver as a module, choose M here: the module 233 To compile this driver as a module, choose M here: the module
229 will be called snd-cs5535audio. 234 will be called snd-cs5535audio.
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index d05200741ac3..0abf2808d59f 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -253,6 +253,8 @@ void snd_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short va
253 ac97->bus->ops->write(ac97, reg, value); 253 ac97->bus->ops->write(ac97, reg, value);
254} 254}
255 255
256EXPORT_SYMBOL(snd_ac97_write);
257
256/** 258/**
257 * snd_ac97_read - read a value from the given register 259 * snd_ac97_read - read a value from the given register
258 * 260 *
@@ -281,6 +283,8 @@ static inline unsigned short snd_ac97_read_cache(struct snd_ac97 *ac97, unsigned
281 return ac97->regs[reg]; 283 return ac97->regs[reg];
282} 284}
283 285
286EXPORT_SYMBOL(snd_ac97_read);
287
284/** 288/**
285 * snd_ac97_write_cache - write a value on the given register and update the cache 289 * snd_ac97_write_cache - write a value on the given register and update the cache
286 * @ac97: the ac97 instance 290 * @ac97: the ac97 instance
@@ -302,6 +306,8 @@ void snd_ac97_write_cache(struct snd_ac97 *ac97, unsigned short reg, unsigned sh
302 mutex_unlock(&ac97->reg_mutex); 306 mutex_unlock(&ac97->reg_mutex);
303} 307}
304 308
309EXPORT_SYMBOL(snd_ac97_write_cache);
310
305/** 311/**
306 * snd_ac97_update - update the value on the given register 312 * snd_ac97_update - update the value on the given register
307 * @ac97: the ac97 instance 313 * @ac97: the ac97 instance
@@ -331,6 +337,8 @@ int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short va
331 return change; 337 return change;
332} 338}
333 339
340EXPORT_SYMBOL(snd_ac97_update);
341
334/** 342/**
335 * snd_ac97_update_bits - update the bits on the given register 343 * snd_ac97_update_bits - update the bits on the given register
336 * @ac97: the ac97 instance 344 * @ac97: the ac97 instance
@@ -356,6 +364,8 @@ int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned sho
356 return change; 364 return change;
357} 365}
358 366
367EXPORT_SYMBOL(snd_ac97_update_bits);
368
359/* no lock version - see snd_ac97_updat_bits() */ 369/* no lock version - see snd_ac97_updat_bits() */
360int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg, 370int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg,
361 unsigned short mask, unsigned short value) 371 unsigned short mask, unsigned short value)
@@ -563,7 +573,7 @@ AC97_SINGLE("PC Speaker Playback Volume", AC97_PC_BEEP, 1, 15, 1)
563}; 573};
564 574
565static const struct snd_kcontrol_new snd_ac97_controls_mic_boost = 575static const struct snd_kcontrol_new snd_ac97_controls_mic_boost =
566 AC97_SINGLE("Mic Boost (+20dB)", AC97_MIC, 6, 1, 0); 576 AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_MIC, 6, 1, 0);
567 577
568 578
569static const char* std_rec_sel[] = {"Mic", "CD", "Video", "Aux", "Line", "Mix", "Mix Mono", "Phone"}; 579static const char* std_rec_sel[] = {"Mic", "CD", "Video", "Aux", "Line", "Mix", "Mix Mono", "Phone"};
@@ -605,7 +615,7 @@ AC97_SINGLE("Simulated Stereo Enhancement", AC97_GENERAL_PURPOSE, 14, 1, 0),
605AC97_SINGLE("3D Control - Switch", AC97_GENERAL_PURPOSE, 13, 1, 0), 615AC97_SINGLE("3D Control - Switch", AC97_GENERAL_PURPOSE, 13, 1, 0),
606AC97_SINGLE("Loudness (bass boost)", AC97_GENERAL_PURPOSE, 12, 1, 0), 616AC97_SINGLE("Loudness (bass boost)", AC97_GENERAL_PURPOSE, 12, 1, 0),
607AC97_ENUM("Mono Output Select", std_enum[2]), 617AC97_ENUM("Mono Output Select", std_enum[2]),
608AC97_ENUM("Mic Select", std_enum[3]), 618AC97_ENUM("Mic Select Capture Switch", std_enum[3]),
609AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0) 619AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0)
610}; 620};
611 621
@@ -1226,7 +1236,8 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1226 ac97->regs[AC97_CENTER_LFE_MASTER] = 0x8080; 1236 ac97->regs[AC97_CENTER_LFE_MASTER] = 0x8080;
1227 1237
1228 /* build center controls */ 1238 /* build center controls */
1229 if (snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER)) { 1239 if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER))
1240 && !(ac97->flags & AC97_AD_MULTI)) {
1230 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_center[0], ac97))) < 0) 1241 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_center[0], ac97))) < 0)
1231 return err; 1242 return err;
1232 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_center[1], ac97))) < 0) 1243 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_center[1], ac97))) < 0)
@@ -1238,7 +1249,8 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1238 } 1249 }
1239 1250
1240 /* build LFE controls */ 1251 /* build LFE controls */
1241 if (snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER+1)) { 1252 if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER+1))
1253 && !(ac97->flags & AC97_AD_MULTI)) {
1242 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_lfe[0], ac97))) < 0) 1254 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_lfe[0], ac97))) < 0)
1243 return err; 1255 return err;
1244 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_lfe[1], ac97))) < 0) 1256 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_lfe[1], ac97))) < 0)
@@ -1250,7 +1262,8 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1250 } 1262 }
1251 1263
1252 /* build surround controls */ 1264 /* build surround controls */
1253 if (snd_ac97_try_volume_mix(ac97, AC97_SURROUND_MASTER)) { 1265 if ((snd_ac97_try_volume_mix(ac97, AC97_SURROUND_MASTER))
1266 && !(ac97->flags & AC97_AD_MULTI)) {
1254 /* Surround Master (0x38) is with stereo mutes */ 1267 /* Surround Master (0x38) is with stereo mutes */
1255 if ((err = snd_ac97_cmix_new_stereo(card, "Surround Playback", AC97_SURROUND_MASTER, 1, ac97)) < 0) 1268 if ((err = snd_ac97_cmix_new_stereo(card, "Surround Playback", AC97_SURROUND_MASTER, 1, ac97)) < 0)
1256 return err; 1269 return err;
@@ -1335,9 +1348,11 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1335 } 1348 }
1336 1349
1337 /* build Aux controls */ 1350 /* build Aux controls */
1338 if (snd_ac97_try_volume_mix(ac97, AC97_AUX)) { 1351 if (!(ac97->flags & AC97_HAS_NO_AUX)) {
1339 if ((err = snd_ac97_cmix_new(card, "Aux Playback", AC97_AUX, ac97)) < 0) 1352 if (snd_ac97_try_volume_mix(ac97, AC97_AUX)) {
1340 return err; 1353 if ((err = snd_ac97_cmix_new(card, "Aux Playback", AC97_AUX, ac97)) < 0)
1354 return err;
1355 }
1341 } 1356 }
1342 1357
1343 /* build PCM controls */ 1358 /* build PCM controls */
@@ -1682,6 +1697,7 @@ const char *snd_ac97_get_short_name(struct snd_ac97 *ac97)
1682 return "unknown codec"; 1697 return "unknown codec";
1683} 1698}
1684 1699
1700EXPORT_SYMBOL(snd_ac97_get_short_name);
1685 1701
1686/* wait for a while until registers are accessible after RESET 1702/* wait for a while until registers are accessible after RESET
1687 * return 0 if ok, negative not ready 1703 * return 0 if ok, negative not ready
@@ -1774,6 +1790,8 @@ int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops,
1774 return 0; 1790 return 0;
1775} 1791}
1776 1792
1793EXPORT_SYMBOL(snd_ac97_bus);
1794
1777/* stop no dev release warning */ 1795/* stop no dev release warning */
1778static void ac97_device_release(struct device * dev) 1796static void ac97_device_release(struct device * dev)
1779{ 1797{
@@ -2117,6 +2135,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
2117 return 0; 2135 return 0;
2118} 2136}
2119 2137
2138EXPORT_SYMBOL(snd_ac97_mixer);
2120 2139
2121/* 2140/*
2122 * Power down the chip. 2141 * Power down the chip.
@@ -2166,6 +2185,8 @@ void snd_ac97_suspend(struct snd_ac97 *ac97)
2166 snd_ac97_powerdown(ac97); 2185 snd_ac97_powerdown(ac97);
2167} 2186}
2168 2187
2188EXPORT_SYMBOL(snd_ac97_suspend);
2189
2169/* 2190/*
2170 * restore ac97 status 2191 * restore ac97 status
2171 */ 2192 */
@@ -2267,6 +2288,8 @@ __reset_ready:
2267 snd_ac97_restore_iec958(ac97); 2288 snd_ac97_restore_iec958(ac97);
2268 } 2289 }
2269} 2290}
2291
2292EXPORT_SYMBOL(snd_ac97_resume);
2270#endif 2293#endif
2271 2294
2272 2295
@@ -2590,29 +2613,7 @@ int snd_ac97_tune_hardware(struct snd_ac97 *ac97, struct ac97_quirk *quirk, cons
2590 return 0; 2613 return 0;
2591} 2614}
2592 2615
2593
2594/*
2595 * Exported symbols
2596 */
2597
2598EXPORT_SYMBOL(snd_ac97_write);
2599EXPORT_SYMBOL(snd_ac97_read);
2600EXPORT_SYMBOL(snd_ac97_write_cache);
2601EXPORT_SYMBOL(snd_ac97_update);
2602EXPORT_SYMBOL(snd_ac97_update_bits);
2603EXPORT_SYMBOL(snd_ac97_get_short_name);
2604EXPORT_SYMBOL(snd_ac97_bus);
2605EXPORT_SYMBOL(snd_ac97_mixer);
2606EXPORT_SYMBOL(snd_ac97_pcm_assign);
2607EXPORT_SYMBOL(snd_ac97_pcm_open);
2608EXPORT_SYMBOL(snd_ac97_pcm_close);
2609EXPORT_SYMBOL(snd_ac97_pcm_double_rate_rules);
2610EXPORT_SYMBOL(snd_ac97_tune_hardware); 2616EXPORT_SYMBOL(snd_ac97_tune_hardware);
2611EXPORT_SYMBOL(snd_ac97_set_rate);
2612#ifdef CONFIG_PM
2613EXPORT_SYMBOL(snd_ac97_resume);
2614EXPORT_SYMBOL(snd_ac97_suspend);
2615#endif
2616 2617
2617/* 2618/*
2618 * INIT part 2619 * INIT part
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 4d9cf37300f7..7f197c780816 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -464,6 +464,10 @@ int patch_wolfson05(struct snd_ac97 * ac97)
464{ 464{
465 /* WM9705, WM9710 */ 465 /* WM9705, WM9710 */
466 ac97->build_ops = &patch_wolfson_wm9705_ops; 466 ac97->build_ops = &patch_wolfson_wm9705_ops;
467#ifdef CONFIG_TOUCHSCREEN_WM9705
468 /* WM9705 touchscreen uses AUX and VIDEO for touch */
469 ac97->flags |=3D AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX;
470#endif
467 return 0; 471 return 0;
468} 472}
469 473
@@ -1367,6 +1371,13 @@ static void ad18xx_resume(struct snd_ac97 *ac97)
1367 1371
1368 snd_ac97_restore_iec958(ac97); 1372 snd_ac97_restore_iec958(ac97);
1369} 1373}
1374
1375static void ad1888_resume(struct snd_ac97 *ac97)
1376{
1377 ad18xx_resume(ac97);
1378 snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x8080);
1379}
1380
1370#endif 1381#endif
1371 1382
1372int patch_ad1819(struct snd_ac97 * ac97) 1383int patch_ad1819(struct snd_ac97 * ac97)
@@ -1627,6 +1638,7 @@ static const struct snd_kcontrol_new snd_ac97_ad1981x_jack_sense[] = {
1627 * (SS vendor << 16 | device) 1638 * (SS vendor << 16 | device)
1628 */ 1639 */
1629static unsigned int ad1981_jacks_blacklist[] = { 1640static unsigned int ad1981_jacks_blacklist[] = {
1641 0x10140537, /* Thinkpad T41p */
1630 0x10140554, /* Thinkpad T42p/R50p */ 1642 0x10140554, /* Thinkpad T42p/R50p */
1631 0 /* end */ 1643 0 /* end */
1632}; 1644};
@@ -1839,7 +1851,7 @@ static struct snd_ac97_build_ops patch_ad1888_build_ops = {
1839 .build_post_spdif = patch_ad198x_post_spdif, 1851 .build_post_spdif = patch_ad198x_post_spdif,
1840 .build_specific = patch_ad1888_specific, 1852 .build_specific = patch_ad1888_specific,
1841#ifdef CONFIG_PM 1853#ifdef CONFIG_PM
1842 .resume = ad18xx_resume, 1854 .resume = ad1888_resume,
1843#endif 1855#endif
1844 .update_jacks = ad1888_update_jacks, 1856 .update_jacks = ad1888_update_jacks,
1845}; 1857};
@@ -2048,7 +2060,10 @@ int patch_alc650(struct snd_ac97 * ac97)
2048 /* Enable SPDIF-IN only on Rev.E and above */ 2060 /* Enable SPDIF-IN only on Rev.E and above */
2049 val = snd_ac97_read(ac97, AC97_ALC650_CLOCK); 2061 val = snd_ac97_read(ac97, AC97_ALC650_CLOCK);
2050 /* SPDIF IN with pin 47 */ 2062 /* SPDIF IN with pin 47 */
2051 if (ac97->spec.dev_flags) 2063 if (ac97->spec.dev_flags &&
2064 /* ASUS A6KM requires EAPD */
2065 ! (ac97->subsystem_vendor == 0x1043 &&
2066 ac97->subsystem_device == 0x1103))
2052 val |= 0x03; /* enable */ 2067 val |= 0x03; /* enable */
2053 else 2068 else
2054 val &= ~0x03; /* disable */ 2069 val &= ~0x03; /* disable */
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c
index 512a3583b0ce..f684aa2c0067 100644
--- a/sound/pci/ac97/ac97_pcm.c
+++ b/sound/pci/ac97/ac97_pcm.c
@@ -317,6 +317,8 @@ int snd_ac97_set_rate(struct snd_ac97 *ac97, int reg, unsigned int rate)
317 return 0; 317 return 0;
318} 318}
319 319
320EXPORT_SYMBOL(snd_ac97_set_rate);
321
320static unsigned short get_pslots(struct snd_ac97 *ac97, unsigned char *rate_table, unsigned short *spdif_slots) 322static unsigned short get_pslots(struct snd_ac97 *ac97, unsigned char *rate_table, unsigned short *spdif_slots)
321{ 323{
322 if (!ac97_is_audio(ac97)) 324 if (!ac97_is_audio(ac97))
@@ -550,6 +552,8 @@ int snd_ac97_pcm_assign(struct snd_ac97_bus *bus,
550 return 0; 552 return 0;
551} 553}
552 554
555EXPORT_SYMBOL(snd_ac97_pcm_assign);
556
553/** 557/**
554 * snd_ac97_pcm_open - opens the given AC97 pcm 558 * snd_ac97_pcm_open - opens the given AC97 pcm
555 * @pcm: the ac97 pcm instance 559 * @pcm: the ac97 pcm instance
@@ -633,6 +637,8 @@ int snd_ac97_pcm_open(struct ac97_pcm *pcm, unsigned int rate,
633 return err; 637 return err;
634} 638}
635 639
640EXPORT_SYMBOL(snd_ac97_pcm_open);
641
636/** 642/**
637 * snd_ac97_pcm_close - closes the given AC97 pcm 643 * snd_ac97_pcm_close - closes the given AC97 pcm
638 * @pcm: the ac97 pcm instance 644 * @pcm: the ac97 pcm instance
@@ -658,6 +664,8 @@ int snd_ac97_pcm_close(struct ac97_pcm *pcm)
658 return 0; 664 return 0;
659} 665}
660 666
667EXPORT_SYMBOL(snd_ac97_pcm_close);
668
661static int double_rate_hw_constraint_rate(struct snd_pcm_hw_params *params, 669static int double_rate_hw_constraint_rate(struct snd_pcm_hw_params *params,
662 struct snd_pcm_hw_rule *rule) 670 struct snd_pcm_hw_rule *rule)
663{ 671{
@@ -709,3 +717,5 @@ int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime)
709 SNDRV_PCM_HW_PARAM_RATE, -1); 717 SNDRV_PCM_HW_PARAM_RATE, -1);
710 return err; 718 return err;
711} 719}
720
721EXPORT_SYMBOL(snd_ac97_pcm_double_rate_rules);
diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c
index 4d523df79cc7..2118df50b9d6 100644
--- a/sound/pci/ac97/ac97_proc.c
+++ b/sound/pci/ac97/ac97_proc.c
@@ -433,7 +433,7 @@ void snd_ac97_proc_init(struct snd_ac97 * ac97)
433 prefix = ac97_is_audio(ac97) ? "ac97" : "mc97"; 433 prefix = ac97_is_audio(ac97) ? "ac97" : "mc97";
434 sprintf(name, "%s#%d-%d", prefix, ac97->addr, ac97->num); 434 sprintf(name, "%s#%d-%d", prefix, ac97->addr, ac97->num);
435 if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) { 435 if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) {
436 snd_info_set_text_ops(entry, ac97, 1024, snd_ac97_proc_read); 436 snd_info_set_text_ops(entry, ac97, snd_ac97_proc_read);
437 if (snd_info_register(entry) < 0) { 437 if (snd_info_register(entry) < 0) {
438 snd_info_free_entry(entry); 438 snd_info_free_entry(entry);
439 entry = NULL; 439 entry = NULL;
@@ -442,10 +442,9 @@ void snd_ac97_proc_init(struct snd_ac97 * ac97)
442 ac97->proc = entry; 442 ac97->proc = entry;
443 sprintf(name, "%s#%d-%d+regs", prefix, ac97->addr, ac97->num); 443 sprintf(name, "%s#%d-%d+regs", prefix, ac97->addr, ac97->num);
444 if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) { 444 if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) {
445 snd_info_set_text_ops(entry, ac97, 1024, snd_ac97_proc_regs_read); 445 snd_info_set_text_ops(entry, ac97, snd_ac97_proc_regs_read);
446#ifdef CONFIG_SND_DEBUG 446#ifdef CONFIG_SND_DEBUG
447 entry->mode |= S_IWUSR; 447 entry->mode |= S_IWUSR;
448 entry->c.text.write_size = 1024;
449 entry->c.text.write = snd_ac97_proc_regs_write; 448 entry->c.text.write = snd_ac97_proc_regs_write;
450#endif 449#endif
451 if (snd_info_register(entry) < 0) { 450 if (snd_info_register(entry) < 0) {
diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c
index 0fb7b3407312..94c26ec05882 100644
--- a/sound/pci/ac97/ak4531_codec.c
+++ b/sound/pci/ac97/ak4531_codec.c
@@ -453,7 +453,7 @@ static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak453
453 struct snd_info_entry *entry; 453 struct snd_info_entry *entry;
454 454
455 if (! snd_card_proc_new(card, "ak4531", &entry)) 455 if (! snd_card_proc_new(card, "ak4531", &entry))
456 snd_info_set_text_ops(entry, ak4531, 1024, snd_ak4531_proc_read); 456 snd_info_set_text_ops(entry, ak4531, snd_ak4531_proc_read);
457} 457}
458#endif 458#endif
459 459
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index eece1c7e55a0..d42bf4570367 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -753,7 +753,7 @@ snd_ad1889_proc_init(struct snd_ad1889 *chip)
753 struct snd_info_entry *entry; 753 struct snd_info_entry *entry;
754 754
755 if (!snd_card_proc_new(chip->card, chip->card->driver, &entry)) 755 if (!snd_card_proc_new(chip->card, chip->card->driver, &entry))
756 snd_info_set_text_ops(entry, chip, 1024, snd_ad1889_proc_read); 756 snd_info_set_text_ops(entry, chip, snd_ad1889_proc_read);
757} 757}
758 758
759static struct ac97_quirk ac97_quirks[] = { 759static struct ac97_quirk ac97_quirks[] = {
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index e2dbc2118902..5dfdbf6657f2 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -49,7 +49,7 @@ MODULE_SUPPORTED_DEVICE("{{ALI,M5451,pci},{ALI,M5451}}");
49static int index = SNDRV_DEFAULT_IDX1; /* Index */ 49static int index = SNDRV_DEFAULT_IDX1; /* Index */
50static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ 50static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
51static int pcm_channels = 32; 51static int pcm_channels = 32;
52static int spdif = 0; 52static int spdif;
53 53
54module_param(index, int, 0444); 54module_param(index, int, 0444);
55MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio."); 55MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio.");
@@ -2173,7 +2173,7 @@ static void __devinit snd_ali_proc_init(struct snd_ali *codec)
2173{ 2173{
2174 struct snd_info_entry *entry; 2174 struct snd_info_entry *entry;
2175 if(!snd_card_proc_new(codec->card, "ali5451", &entry)) 2175 if(!snd_card_proc_new(codec->card, "ali5451", &entry))
2176 snd_info_set_text_ops(entry, codec, 1024, snd_ali_proc_read); 2176 snd_info_set_text_ops(entry, codec, snd_ali_proc_read);
2177} 2177}
2178 2178
2179static int __devinit snd_ali_resources(struct snd_ali *codec) 2179static int __devinit snd_ali_resources(struct snd_ali *codec)
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 60423b1c678b..a9f08066459a 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -746,8 +746,8 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
746 card->shortname, chip->alt_port, chip->irq); 746 card->shortname, chip->alt_port, chip->irq);
747 747
748 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000, 748 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000,
749 gcr+0x30, 1, pci->irq, 0, 749 gcr+0x30, MPU401_INFO_INTEGRATED,
750 &chip->rmidi)) < 0) { 750 pci->irq, 0, &chip->rmidi)) < 0) {
751 printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", gcr+0x30); 751 printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", gcr+0x30);
752 goto out_err; 752 goto out_err;
753 } 753 }
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index d0f759d86d3d..f18a8c0e4688 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1504,7 +1504,7 @@ static void __devinit snd_atiixp_proc_init(struct atiixp *chip)
1504 struct snd_info_entry *entry; 1504 struct snd_info_entry *entry;
1505 1505
1506 if (! snd_card_proc_new(chip->card, "atiixp", &entry)) 1506 if (! snd_card_proc_new(chip->card, "atiixp", &entry))
1507 snd_info_set_text_ops(entry, chip, 1024, snd_atiixp_proc_read); 1507 snd_info_set_text_ops(entry, chip, snd_atiixp_proc_read);
1508} 1508}
1509#else /* !CONFIG_PROC_FS */ 1509#else /* !CONFIG_PROC_FS */
1510#define snd_atiixp_proc_init(chip) 1510#define snd_atiixp_proc_init(chip)
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 12a34c39caa7..40739057076b 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1177,7 +1177,7 @@ static void __devinit snd_atiixp_proc_init(struct atiixp_modem *chip)
1177 struct snd_info_entry *entry; 1177 struct snd_info_entry *entry;
1178 1178
1179 if (! snd_card_proc_new(chip->card, "atiixp-modem", &entry)) 1179 if (! snd_card_proc_new(chip->card, "atiixp-modem", &entry))
1180 snd_info_set_text_ops(entry, chip, 1024, snd_atiixp_proc_read); 1180 snd_info_set_text_ops(entry, chip, snd_atiixp_proc_read);
1181} 1181}
1182#else 1182#else
1183#define snd_atiixp_proc_init(chip) 1183#define snd_atiixp_proc_init(chip)
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 126870ec063a..8a3b118989bf 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -261,6 +261,13 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
261 return err; 261 return err;
262 } 262 }
263 snd_vortex_workaround(pci, pcifix[dev]); 263 snd_vortex_workaround(pci, pcifix[dev]);
264
265 // Card details needed in snd_vortex_midi
266 strcpy(card->driver, CARD_NAME_SHORT);
267 sprintf(card->shortname, "Aureal Vortex %s", CARD_NAME_SHORT);
268 sprintf(card->longname, "%s at 0x%lx irq %i",
269 card->shortname, chip->io, chip->irq);
270
264 // (4) Alloc components. 271 // (4) Alloc components.
265 // ADB pcm. 272 // ADB pcm.
266 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_ADB)) < 0) { 273 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_ADB)) < 0) {
@@ -323,11 +330,6 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
323#endif 330#endif
324 331
325 // (5) 332 // (5)
326 strcpy(card->driver, CARD_NAME_SHORT);
327 strcpy(card->shortname, CARD_NAME_SHORT);
328 sprintf(card->longname, "%s at 0x%lx irq %i",
329 card->shortname, chip->io, chip->irq);
330
331 if ((err = pci_read_config_word(pci, PCI_DEVICE_ID, 333 if ((err = pci_read_config_word(pci, PCI_DEVICE_ID,
332 &(chip->device))) < 0) { 334 &(chip->device))) < 0) {
333 snd_card_free(card); 335 snd_card_free(card);
diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c
index 873f486b07b8..c75d368ea087 100644
--- a/sound/pci/au88x0/au88x0_mpu401.c
+++ b/sound/pci/au88x0/au88x0_mpu401.c
@@ -47,7 +47,7 @@ static int __devinit snd_vortex_midi(vortex_t * vortex)
47 struct snd_rawmidi *rmidi; 47 struct snd_rawmidi *rmidi;
48 int temp, mode; 48 int temp, mode;
49 struct snd_mpu401 *mpu; 49 struct snd_mpu401 *mpu;
50 int port; 50 unsigned long port;
51 51
52#ifdef VORTEX_MPU401_LEGACY 52#ifdef VORTEX_MPU401_LEGACY
53 /* EnableHardCodedMPU401Port() */ 53 /* EnableHardCodedMPU401Port() */
@@ -70,9 +70,6 @@ static int __devinit snd_vortex_midi(vortex_t * vortex)
70 temp |= (MIDI_CLOCK_DIV << 8) | ((mode >> 24) & 0xff) << 4; 70 temp |= (MIDI_CLOCK_DIV << 8) | ((mode >> 24) & 0xff) << 4;
71 hwwrite(vortex->mmio, VORTEX_CTRL2, temp); 71 hwwrite(vortex->mmio, VORTEX_CTRL2, temp);
72 hwwrite(vortex->mmio, VORTEX_MIDI_CMD, MPU401_RESET); 72 hwwrite(vortex->mmio, VORTEX_MIDI_CMD, MPU401_RESET);
73 /* Set some kind of mode */
74 if (mode)
75 hwwrite(vortex->mmio, VORTEX_MIDI_CMD, MPU401_ENTER_UART);
76 73
77 /* Check if anything is OK. */ 74 /* Check if anything is OK. */
78 temp = hwread(vortex->mmio, VORTEX_MIDI_DATA); 75 temp = hwread(vortex->mmio, VORTEX_MIDI_DATA);
@@ -98,7 +95,8 @@ static int __devinit snd_vortex_midi(vortex_t * vortex)
98 port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA); 95 port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA);
99 if ((temp = 96 if ((temp =
100 snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port, 97 snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port,
101 1, 0, 0, &rmidi)) != 0) { 98 MPU401_INFO_INTEGRATED | MPU401_INFO_MMIO,
99 0, 0, &rmidi)) != 0) {
102 hwwrite(vortex->mmio, VORTEX_CTRL, 100 hwwrite(vortex->mmio, VORTEX_CTRL,
103 (hwread(vortex->mmio, VORTEX_CTRL) & 101 (hwread(vortex->mmio, VORTEX_CTRL) &
104 ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN); 102 ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN);
@@ -107,6 +105,9 @@ static int __devinit snd_vortex_midi(vortex_t * vortex)
107 mpu = rmidi->private_data; 105 mpu = rmidi->private_data;
108 mpu->cport = (unsigned long)(vortex->mmio + VORTEX_MIDI_CMD); 106 mpu->cport = (unsigned long)(vortex->mmio + VORTEX_MIDI_CMD);
109#endif 107#endif
108 /* Overwrite MIDI name */
109 snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI %d", CARD_NAME_SHORT , vortex->card->number);
110
110 vortex->rmidi = rmidi; 111 vortex->rmidi = rmidi;
111 return 0; 112 return 0;
112} 113}
diff --git a/sound/pci/au88x0/au88x0_xtalk.c b/sound/pci/au88x0/au88x0_xtalk.c
index 4534e1882ada..b4151e208b71 100644
--- a/sound/pci/au88x0/au88x0_xtalk.c
+++ b/sound/pci/au88x0/au88x0_xtalk.c
@@ -66,31 +66,20 @@ static xtalk_gains_t const asXtalkGainsAllChan = {
66 0 66 0
67 //0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff 67 //0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff
68}; 68};
69static xtalk_gains_t const asXtalkGainsZeros = { 69static xtalk_gains_t const asXtalkGainsZeros;
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
71};
72 70
73static xtalk_dline_t const alXtalkDlineZeros = { 71static xtalk_dline_t const alXtalkDlineZeros;
74 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0
77};
78static xtalk_dline_t const alXtalkDlineTest = { 72static xtalk_dline_t const alXtalkDlineTest = {
79 0xFC18, 0x03E8FFFF, 0x186A0, 0x7960FFFE, 1, 0xFFFFFFFF, 73 0xFC18, 0x03E8FFFF, 0x186A0, 0x7960FFFE, 1, 0xFFFFFFFF,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0 75 0, 0, 0, 0
82}; 76};
83 77
84static xtalk_instate_t const asXtalkInStateZeros = { 0, 0, 0, 0 }; 78static xtalk_instate_t const asXtalkInStateZeros;
85static xtalk_instate_t const asXtalkInStateTest = 79static xtalk_instate_t const asXtalkInStateTest =
86 { 0xFF80, 0x0080, 0xFFFF, 0x0001 }; 80 { 0xFF80, 0x0080, 0xFFFF, 0x0001 };
87static xtalk_state_t const asXtalkOutStateZeros = { 81static xtalk_state_t const asXtalkOutStateZeros;
88 {0, 0, 0, 0}, 82
89 {0, 0, 0, 0},
90 {0, 0, 0, 0},
91 {0, 0, 0, 0},
92 {0, 0, 0, 0}
93};
94static short const sDiamondKLeftEq = 0x401d; 83static short const sDiamondKLeftEq = 0x401d;
95static short const sDiamondKRightEq = 0x401d; 84static short const sDiamondKRightEq = 0x401d;
96static short const sDiamondKLeftXt = 0xF90E; 85static short const sDiamondKLeftXt = 0xF90E;
@@ -162,13 +151,7 @@ static xtalk_coefs_t const asXtalkNarrowCoefsRightXt = {
162 {0, 0, 0, 0, 0} 151 {0, 0, 0, 0, 0}
163}; 152};
164 153
165static xtalk_coefs_t const asXtalkCoefsZeros = { 154static xtalk_coefs_t const asXtalkCoefsZeros;
166 {0, 0, 0, 0, 0},
167 {0, 0, 0, 0, 0},
168 {0, 0, 0, 0, 0},
169 {0, 0, 0, 0, 0},
170 {0, 0, 0, 0, 0}
171};
172static xtalk_coefs_t const asXtalkCoefsPipe = { 155static xtalk_coefs_t const asXtalkCoefsPipe = {
173 {0, 0, 0x0FA0, 0, 0}, 156 {0, 0, 0x0FA0, 0, 0},
174 {0, 0, 0x0FA0, 0, 0}, 157 {0, 0, 0x0FA0, 0, 0},
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 52a364524262..6e62dafb66cd 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -33,14 +33,21 @@
33 * in the first place >:-P}), 33 * in the first place >:-P}),
34 * I was forced to base this driver on reverse engineering 34 * I was forced to base this driver on reverse engineering
35 * (3 weeks' worth of evenings filled with driver work). 35 * (3 weeks' worth of evenings filled with driver work).
36 * (and no, I did NOT go the easy way: to pick up a PCI128 for 9 Euros) 36 * (and no, I did NOT go the easy way: to pick up a SB PCI128 for 9 Euros)
37 * 37 *
38 * The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name 38 * The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name
39 * for compatibility reasons) has the following features: 39 * for compatibility reasons) has the following features:
40 * 40 *
41 * - builtin AC97 conformant codec (SNR over 80dB) 41 * - builtin AC97 conformant codec (SNR over 80dB)
42 * (really AC97 compliant?? I really doubt it when looking 42 * Note that "conformant" != "compliant"!! this chip's mixer register layout
43 * at the mixer register layout) 43 * *differs* from the standard AC97 layout:
44 * they chose to not implement the headphone register (which is not a
45 * problem since it's merely optional), yet when doing this, they committed
46 * the grave sin of letting other registers follow immediately instead of
47 * keeping a headphone dummy register, thereby shifting the mixer register
48 * addresses illegally. So far unfortunately it looks like the very flexible
49 * ALSA AC97 support is still not enough to easily compensate for such a
50 * grave layout violation despite all tweaks and quirks mechanisms it offers.
44 * - builtin genuine OPL3 51 * - builtin genuine OPL3
45 * - full duplex 16bit playback/record at independent sampling rate 52 * - full duplex 16bit playback/record at independent sampling rate
46 * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr?? 53 * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr??
@@ -90,10 +97,15 @@
90 * 97 *
91 * TODO 98 * TODO
92 * - test MPU401 MIDI playback etc. 99 * - test MPU401 MIDI playback etc.
93 * - power management. See e.g. intel8x0 or cs4281. 100 * - add some power micro-management (disable various units of the card
94 * This would be nice since the chip runs a bit hot, and it's *required* 101 * as long as they're unused). However this requires I/O ports which I
95 * anyway for proper ACPI power management. 102 * haven't figured out yet and which thus might not even exist...
103 * The standard suspend/resume functionality could probably make use of
104 * some improvement, too...
96 * - figure out what all unknown port bits are responsible for 105 * - figure out what all unknown port bits are responsible for
106 * - figure out some cleverly evil scheme to possibly make ALSA AC97 code
107 * fully accept our quite incompatible ""AC97"" mixer and thus save some
108 * code (but I'm not too optimistic that doing this is possible at all)
97 */ 109 */
98 110
99#include <sound/driver.h> 111#include <sound/driver.h>
@@ -214,6 +226,16 @@ struct snd_azf3328 {
214 226
215 struct pci_dev *pci; 227 struct pci_dev *pci;
216 int irq; 228 int irq;
229
230#ifdef CONFIG_PM
231 /* register value containers for power management
232 * Note: not always full I/O range preserved (just like Win driver!) */
233 u16 saved_regs_codec [AZF_IO_SIZE_CODEC_PM / 2];
234 u16 saved_regs_io2 [AZF_IO_SIZE_IO2_PM / 2];
235 u16 saved_regs_mpu [AZF_IO_SIZE_MPU_PM / 2];
236 u16 saved_regs_synth[AZF_IO_SIZE_SYNTH_PM / 2];
237 u16 saved_regs_mixer[AZF_IO_SIZE_MIXER_PM / 2];
238#endif
217}; 239};
218 240
219static const struct pci_device_id snd_azf3328_ids[] __devinitdata = { 241static const struct pci_device_id snd_azf3328_ids[] __devinitdata = {
@@ -317,10 +339,8 @@ snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg
317 else 339 else
318 dst_vol_left &= ~0x80; 340 dst_vol_left &= ~0x80;
319 341
320 do 342 do {
321 { 343 if (!left_done) {
322 if (!left_done)
323 {
324 if (curr_vol_left > dst_vol_left) 344 if (curr_vol_left > dst_vol_left)
325 curr_vol_left--; 345 curr_vol_left--;
326 else 346 else
@@ -330,8 +350,7 @@ snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg
330 left_done = 1; 350 left_done = 1;
331 outb(curr_vol_left, portbase + 1); 351 outb(curr_vol_left, portbase + 1);
332 } 352 }
333 if (!right_done) 353 if (!right_done) {
334 {
335 if (curr_vol_right > dst_vol_right) 354 if (curr_vol_right > dst_vol_right)
336 curr_vol_right--; 355 curr_vol_right--;
337 else 356 else
@@ -346,8 +365,7 @@ snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg
346 } 365 }
347 if (delay) 366 if (delay)
348 mdelay(delay); 367 mdelay(delay);
349 } 368 } while ((!left_done) || (!right_done));
350 while ((!left_done) || (!right_done));
351 snd_azf3328_dbgcallleave(); 369 snd_azf3328_dbgcallleave();
352} 370}
353 371
@@ -514,15 +532,18 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
514 struct snd_ctl_elem_info *uinfo) 532 struct snd_ctl_elem_info *uinfo)
515{ 533{
516 static const char * const texts1[] = { 534 static const char * const texts1[] = {
517 "ModemOut1", "ModemOut2" 535 "Mic1", "Mic2"
518 }; 536 };
519 static const char * const texts2[] = { 537 static const char * const texts2[] = {
520 "MonoSelectSource1", "MonoSelectSource2" 538 "Mix", "Mic"
521 }; 539 };
522 static const char * const texts3[] = { 540 static const char * const texts3[] = {
523 "Mic", "CD", "Video", "Aux", 541 "Mic", "CD", "Video", "Aux",
524 "Line", "Mix", "Mix Mono", "Phone" 542 "Line", "Mix", "Mix Mono", "Phone"
525 }; 543 };
544 static const char * const texts4[] = {
545 "pre 3D", "post 3D"
546 };
526 struct azf3328_mixer_reg reg; 547 struct azf3328_mixer_reg reg;
527 548
528 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 549 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
@@ -531,14 +552,19 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
531 uinfo->value.enumerated.items = reg.enum_c; 552 uinfo->value.enumerated.items = reg.enum_c;
532 if (uinfo->value.enumerated.item > reg.enum_c - 1U) 553 if (uinfo->value.enumerated.item > reg.enum_c - 1U)
533 uinfo->value.enumerated.item = reg.enum_c - 1U; 554 uinfo->value.enumerated.item = reg.enum_c - 1U;
534 if (reg.reg == IDX_MIXER_ADVCTL2) 555 if (reg.reg == IDX_MIXER_ADVCTL2) {
535 { 556 switch(reg.lchan_shift) {
536 if (reg.lchan_shift == 8) /* modem out sel */ 557 case 8: /* modem out sel */
537 strcpy(uinfo->value.enumerated.name, texts1[uinfo->value.enumerated.item]); 558 strcpy(uinfo->value.enumerated.name, texts1[uinfo->value.enumerated.item]);
538 else /* mono sel source */ 559 break;
560 case 9: /* mono sel source */
539 strcpy(uinfo->value.enumerated.name, texts2[uinfo->value.enumerated.item]); 561 strcpy(uinfo->value.enumerated.name, texts2[uinfo->value.enumerated.item]);
540 } 562 break;
541 else 563 case 15: /* PCM Out Path */
564 strcpy(uinfo->value.enumerated.name, texts4[uinfo->value.enumerated.item]);
565 break;
566 }
567 } else
542 strcpy(uinfo->value.enumerated.name, texts3[uinfo->value.enumerated.item] 568 strcpy(uinfo->value.enumerated.name, texts3[uinfo->value.enumerated.item]
543); 569);
544 return 0; 570 return 0;
@@ -554,12 +580,10 @@ snd_azf3328_get_mixer_enum(struct snd_kcontrol *kcontrol,
554 580
555 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 581 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
556 val = snd_azf3328_mixer_inw(chip, reg.reg); 582 val = snd_azf3328_mixer_inw(chip, reg.reg);
557 if (reg.reg == IDX_MIXER_REC_SELECT) 583 if (reg.reg == IDX_MIXER_REC_SELECT) {
558 {
559 ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1); 584 ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
560 ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1); 585 ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1);
561 } 586 } else
562 else
563 ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1); 587 ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
564 588
565 snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n", 589 snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n",
@@ -579,16 +603,13 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
579 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 603 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
580 oreg = snd_azf3328_mixer_inw(chip, reg.reg); 604 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
581 val = oreg; 605 val = oreg;
582 if (reg.reg == IDX_MIXER_REC_SELECT) 606 if (reg.reg == IDX_MIXER_REC_SELECT) {
583 {
584 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U || 607 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U ||
585 ucontrol->value.enumerated.item[1] > reg.enum_c - 1U) 608 ucontrol->value.enumerated.item[1] > reg.enum_c - 1U)
586 return -EINVAL; 609 return -EINVAL;
587 val = (ucontrol->value.enumerated.item[0] << 8) | 610 val = (ucontrol->value.enumerated.item[0] << 8) |
588 (ucontrol->value.enumerated.item[1] << 0); 611 (ucontrol->value.enumerated.item[1] << 0);
589 } 612 } else {
590 else
591 {
592 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U) 613 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U)
593 return -EINVAL; 614 return -EINVAL;
594 val &= ~((reg.enum_c - 1) << reg.lchan_shift); 615 val &= ~((reg.enum_c - 1) << reg.lchan_shift);
@@ -629,13 +650,14 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata
629 AZF3328_MIXER_VOL_MONO("Modem Playback Volume", IDX_MIXER_MODEMOUT, 0x1f, 1), 650 AZF3328_MIXER_VOL_MONO("Modem Playback Volume", IDX_MIXER_MODEMOUT, 0x1f, 1),
630 AZF3328_MIXER_SWITCH("Modem Capture Switch", IDX_MIXER_MODEMIN, 15, 1), 651 AZF3328_MIXER_SWITCH("Modem Capture Switch", IDX_MIXER_MODEMIN, 15, 1),
631 AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1), 652 AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1),
632 AZF3328_MIXER_ENUM("Modem Out Select", IDX_MIXER_ADVCTL2, 2, 8), 653 AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8),
633 AZF3328_MIXER_ENUM("Mono Select Source", IDX_MIXER_ADVCTL2, 2, 9), 654 AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
655 AZF3328_MIXER_ENUM("PCM", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
634 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0), 656 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
635 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0), 657 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
636 AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0), 658 AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
637 AZF3328_MIXER_VOL_SPECIAL("3D Control - Wide", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */ 659 AZF3328_MIXER_VOL_SPECIAL("3D Control - Width", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
638 AZF3328_MIXER_VOL_SPECIAL("3D Control - Space", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */ 660 AZF3328_MIXER_VOL_SPECIAL("3D Control - Depth", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
639#if MIXER_TESTING 661#if MIXER_TESTING
640 AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0), 662 AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0),
641 AZF3328_MIXER_SWITCH("1", IDX_MIXER_ADVCTL2, 1, 0), 663 AZF3328_MIXER_SWITCH("1", IDX_MIXER_ADVCTL2, 1, 0),
@@ -813,22 +835,18 @@ snd_azf3328_setdmaa(struct snd_azf3328 *chip,
813 unsigned int is_running; 835 unsigned int is_running;
814 836
815 snd_azf3328_dbgcallenter(); 837 snd_azf3328_dbgcallenter();
816 if (do_recording) 838 if (do_recording) {
817 {
818 /* access capture registers, i.e. skip playback reg section */ 839 /* access capture registers, i.e. skip playback reg section */
819 portbase = chip->codec_port + 0x20; 840 portbase = chip->codec_port + 0x20;
820 is_running = chip->is_recording; 841 is_running = chip->is_recording;
821 } 842 } else {
822 else
823 {
824 /* access the playback register section */ 843 /* access the playback register section */
825 portbase = chip->codec_port + 0x00; 844 portbase = chip->codec_port + 0x00;
826 is_running = chip->is_playing; 845 is_running = chip->is_playing;
827 } 846 }
828 847
829 /* AZF3328 uses a two buffer pointer DMA playback approach */ 848 /* AZF3328 uses a two buffer pointer DMA playback approach */
830 if (!is_running) 849 if (!is_running) {
831 {
832 unsigned long addr_area2; 850 unsigned long addr_area2;
833 unsigned long count_areas, count_tmp; /* width 32bit -- overflow!! */ 851 unsigned long count_areas, count_tmp; /* width 32bit -- overflow!! */
834 count_areas = size/2; 852 count_areas = size/2;
@@ -961,6 +979,13 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
961 chip->is_playing = 1; 979 chip->is_playing = 1;
962 snd_azf3328_dbgplay("STARTED PLAYBACK\n"); 980 snd_azf3328_dbgplay("STARTED PLAYBACK\n");
963 break; 981 break;
982 case SNDRV_PCM_TRIGGER_RESUME:
983 snd_azf3328_dbgplay("RESUME PLAYBACK\n");
984 /* resume playback if we were active */
985 if (chip->is_playing)
986 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
987 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) | DMA_RESUME);
988 break;
964 case SNDRV_PCM_TRIGGER_STOP: 989 case SNDRV_PCM_TRIGGER_STOP:
965 snd_azf3328_dbgplay("STOP PLAYBACK\n"); 990 snd_azf3328_dbgplay("STOP PLAYBACK\n");
966 991
@@ -988,6 +1013,12 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
988 chip->is_playing = 0; 1013 chip->is_playing = 0;
989 snd_azf3328_dbgplay("STOPPED PLAYBACK\n"); 1014 snd_azf3328_dbgplay("STOPPED PLAYBACK\n");
990 break; 1015 break;
1016 case SNDRV_PCM_TRIGGER_SUSPEND:
1017 snd_azf3328_dbgplay("SUSPEND PLAYBACK\n");
1018 /* make sure playback is stopped */
1019 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1020 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) & ~DMA_RESUME);
1021 break;
991 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1022 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
992 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n"); 1023 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
993 break; 1024 break;
@@ -995,6 +1026,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
995 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n"); 1026 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
996 break; 1027 break;
997 default: 1028 default:
1029 printk(KERN_ERR "FIXME: unknown trigger mode!\n");
998 return -EINVAL; 1030 return -EINVAL;
999 } 1031 }
1000 1032
@@ -1068,6 +1100,13 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1068 chip->is_recording = 1; 1100 chip->is_recording = 1;
1069 snd_azf3328_dbgplay("STARTED CAPTURE\n"); 1101 snd_azf3328_dbgplay("STARTED CAPTURE\n");
1070 break; 1102 break;
1103 case SNDRV_PCM_TRIGGER_RESUME:
1104 snd_azf3328_dbgplay("RESUME CAPTURE\n");
1105 /* resume recording if we were active */
1106 if (chip->is_recording)
1107 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1108 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) | DMA_RESUME);
1109 break;
1071 case SNDRV_PCM_TRIGGER_STOP: 1110 case SNDRV_PCM_TRIGGER_STOP:
1072 snd_azf3328_dbgplay("STOP CAPTURE\n"); 1111 snd_azf3328_dbgplay("STOP CAPTURE\n");
1073 1112
@@ -1088,6 +1127,12 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1088 chip->is_recording = 0; 1127 chip->is_recording = 0;
1089 snd_azf3328_dbgplay("STOPPED CAPTURE\n"); 1128 snd_azf3328_dbgplay("STOPPED CAPTURE\n");
1090 break; 1129 break;
1130 case SNDRV_PCM_TRIGGER_SUSPEND:
1131 snd_azf3328_dbgplay("SUSPEND CAPTURE\n");
1132 /* make sure recording is stopped */
1133 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1134 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) & ~DMA_RESUME);
1135 break;
1091 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1136 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1092 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n"); 1137 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
1093 break; 1138 break;
@@ -1095,6 +1140,7 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1095 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n"); 1140 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1096 break; 1141 break;
1097 default: 1142 default:
1143 printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1098 return -EINVAL; 1144 return -EINVAL;
1099 } 1145 }
1100 1146
@@ -1163,8 +1209,7 @@ snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1163 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE), 1209 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
1164 status); 1210 status);
1165 1211
1166 if (status & IRQ_TIMER) 1212 if (status & IRQ_TIMER) {
1167 {
1168 /* snd_azf3328_dbgplay("timer %ld\n", inl(chip->codec_port+IDX_IO_TIMER_VALUE) & TIMER_VALUE_MASK); */ 1213 /* snd_azf3328_dbgplay("timer %ld\n", inl(chip->codec_port+IDX_IO_TIMER_VALUE) & TIMER_VALUE_MASK); */
1169 if (chip->timer) 1214 if (chip->timer)
1170 snd_timer_interrupt(chip->timer, chip->timer->sticks); 1215 snd_timer_interrupt(chip->timer, chip->timer->sticks);
@@ -1174,50 +1219,43 @@ snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1174 spin_unlock(&chip->reg_lock); 1219 spin_unlock(&chip->reg_lock);
1175 snd_azf3328_dbgplay("azt3328: timer IRQ\n"); 1220 snd_azf3328_dbgplay("azt3328: timer IRQ\n");
1176 } 1221 }
1177 if (status & IRQ_PLAYBACK) 1222 if (status & IRQ_PLAYBACK) {
1178 {
1179 spin_lock(&chip->reg_lock); 1223 spin_lock(&chip->reg_lock);
1180 which = snd_azf3328_codec_inb(chip, IDX_IO_PLAY_IRQTYPE); 1224 which = snd_azf3328_codec_inb(chip, IDX_IO_PLAY_IRQTYPE);
1181 /* ack all IRQ types immediately */ 1225 /* ack all IRQ types immediately */
1182 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which); 1226 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which);
1183 spin_unlock(&chip->reg_lock); 1227 spin_unlock(&chip->reg_lock);
1184 1228
1185 if (chip->pcm && chip->playback_substream) 1229 if (chip->pcm && chip->playback_substream) {
1186 {
1187 snd_pcm_period_elapsed(chip->playback_substream); 1230 snd_pcm_period_elapsed(chip->playback_substream);
1188 snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n", 1231 snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n",
1189 which, 1232 which,
1190 inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS)); 1233 inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
1191 } 1234 } else
1192 else
1193 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n"); 1235 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
1194 if (which & IRQ_PLAY_SOMETHING) 1236 if (which & IRQ_PLAY_SOMETHING)
1195 snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n"); 1237 snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n");
1196 } 1238 }
1197 if (status & IRQ_RECORDING) 1239 if (status & IRQ_RECORDING) {
1198 {
1199 spin_lock(&chip->reg_lock); 1240 spin_lock(&chip->reg_lock);
1200 which = snd_azf3328_codec_inb(chip, IDX_IO_REC_IRQTYPE); 1241 which = snd_azf3328_codec_inb(chip, IDX_IO_REC_IRQTYPE);
1201 /* ack all IRQ types immediately */ 1242 /* ack all IRQ types immediately */
1202 snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which); 1243 snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which);
1203 spin_unlock(&chip->reg_lock); 1244 spin_unlock(&chip->reg_lock);
1204 1245
1205 if (chip->pcm && chip->capture_substream) 1246 if (chip->pcm && chip->capture_substream) {
1206 {
1207 snd_pcm_period_elapsed(chip->capture_substream); 1247 snd_pcm_period_elapsed(chip->capture_substream);
1208 snd_azf3328_dbgplay("REC period done (#%x), @ %x\n", 1248 snd_azf3328_dbgplay("REC period done (#%x), @ %x\n",
1209 which, 1249 which,
1210 inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS)); 1250 inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
1211 } 1251 } else
1212 else
1213 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n"); 1252 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
1214 if (which & IRQ_REC_SOMETHING) 1253 if (which & IRQ_REC_SOMETHING)
1215 snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n"); 1254 snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n");
1216 } 1255 }
1217 /* MPU401 has less critical IRQ requirements 1256 /* MPU401 has less critical IRQ requirements
1218 * than timer and playback/recording, right? */ 1257 * than timer and playback/recording, right? */
1219 if (status & IRQ_MPU401) 1258 if (status & IRQ_MPU401) {
1220 {
1221 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); 1259 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
1222 1260
1223 /* hmm, do we have to ack the IRQ here somehow? 1261 /* hmm, do we have to ack the IRQ here somehow?
@@ -1511,8 +1549,7 @@ snd_azf3328_timer_start(struct snd_timer *timer)
1511 snd_azf3328_dbgcallenter(); 1549 snd_azf3328_dbgcallenter();
1512 chip = snd_timer_chip(timer); 1550 chip = snd_timer_chip(timer);
1513 delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK; 1551 delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
1514 if (delay < 49) 1552 if (delay < 49) {
1515 {
1516 /* uhoh, that's not good, since user-space won't know about 1553 /* uhoh, that's not good, since user-space won't know about
1517 * this timing tweak 1554 * this timing tweak
1518 * (we need to do it to avoid a lockup, though) */ 1555 * (we need to do it to avoid a lockup, though) */
@@ -1766,9 +1803,11 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
1766 goto out_err; 1803 goto out_err;
1767 } 1804 }
1768 1805
1806 card->private_data = chip;
1807
1769 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401, 1808 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401,
1770 chip->mpu_port, 1, pci->irq, 0, 1809 chip->mpu_port, MPU401_INFO_INTEGRATED,
1771 &chip->rmidi)) < 0) { 1810 pci->irq, 0, &chip->rmidi)) < 0) {
1772 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port); 1811 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);
1773 goto out_err; 1812 goto out_err;
1774 } 1813 }
@@ -1791,6 +1830,8 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
1791 } 1830 }
1792 } 1831 }
1793 1832
1833 opl3->private_data = chip;
1834
1794 sprintf(card->longname, "%s at 0x%lx, irq %i", 1835 sprintf(card->longname, "%s at 0x%lx, irq %i",
1795 card->shortname, chip->codec_port, chip->irq); 1836 card->shortname, chip->codec_port, chip->irq);
1796 1837
@@ -1834,11 +1875,80 @@ snd_azf3328_remove(struct pci_dev *pci)
1834 snd_azf3328_dbgcallleave(); 1875 snd_azf3328_dbgcallleave();
1835} 1876}
1836 1877
1878#ifdef CONFIG_PM
1879static int
1880snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
1881{
1882 struct snd_card *card = pci_get_drvdata(pci);
1883 struct snd_azf3328 *chip = card->private_data;
1884 int reg;
1885
1886 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1887
1888 snd_pcm_suspend_all(chip->pcm);
1889
1890 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++)
1891 chip->saved_regs_mixer[reg] = inw(chip->mixer_port + reg * 2);
1892
1893 /* make sure to disable master volume etc. to prevent looping sound */
1894 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
1895 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
1896
1897 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++)
1898 chip->saved_regs_codec[reg] = inw(chip->codec_port + reg * 2);
1899 for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++)
1900 chip->saved_regs_io2[reg] = inw(chip->io2_port + reg * 2);
1901 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++)
1902 chip->saved_regs_mpu[reg] = inw(chip->mpu_port + reg * 2);
1903 for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++)
1904 chip->saved_regs_synth[reg] = inw(chip->synth_port + reg * 2);
1905
1906 pci_set_power_state(pci, PCI_D3hot);
1907 pci_disable_device(pci);
1908 pci_save_state(pci);
1909 return 0;
1910}
1911
1912static int
1913snd_azf3328_resume(struct pci_dev *pci)
1914{
1915 struct snd_card *card = pci_get_drvdata(pci);
1916 struct snd_azf3328 *chip = card->private_data;
1917 int reg;
1918
1919 pci_restore_state(pci);
1920 pci_enable_device(pci);
1921 pci_set_power_state(pci, PCI_D0);
1922 pci_set_master(pci);
1923
1924 for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++)
1925 outw(chip->saved_regs_io2[reg], chip->io2_port + reg * 2);
1926 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++)
1927 outw(chip->saved_regs_mpu[reg], chip->mpu_port + reg * 2);
1928 for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++)
1929 outw(chip->saved_regs_synth[reg], chip->synth_port + reg * 2);
1930 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++)
1931 outw(chip->saved_regs_mixer[reg], chip->mixer_port + reg * 2);
1932 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++)
1933 outw(chip->saved_regs_codec[reg], chip->codec_port + reg * 2);
1934
1935 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1936 return 0;
1937}
1938#endif
1939
1940
1941
1942
1837static struct pci_driver driver = { 1943static struct pci_driver driver = {
1838 .name = "AZF3328", 1944 .name = "AZF3328",
1839 .id_table = snd_azf3328_ids, 1945 .id_table = snd_azf3328_ids,
1840 .probe = snd_azf3328_probe, 1946 .probe = snd_azf3328_probe,
1841 .remove = __devexit_p(snd_azf3328_remove), 1947 .remove = __devexit_p(snd_azf3328_remove),
1948#ifdef CONFIG_PM
1949 .suspend = snd_azf3328_suspend,
1950 .resume = snd_azf3328_resume,
1951#endif
1842}; 1952};
1843 1953
1844static int __init 1954static int __init
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h
index f489bdaf6d40..b4f3e3cd006b 100644
--- a/sound/pci/azt3328.h
+++ b/sound/pci/azt3328.h
@@ -5,6 +5,9 @@
5 5
6/*** main I/O area port indices ***/ 6/*** main I/O area port indices ***/
7/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */ 7/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */
8#define AZF_IO_SIZE_CODEC 0x80
9#define AZF_IO_SIZE_CODEC_PM 0x70
10
8/* the driver initialisation suggests a layout of 4 main areas: 11/* the driver initialisation suggests a layout of 4 main areas:
9 * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe MPU401??). 12 * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe MPU401??).
10 * And another area from 0x60 to 0x6f (DirectX timer, IRQ management, 13 * And another area from 0x60 to 0x6f (DirectX timer, IRQ management,
@@ -87,7 +90,7 @@
87#define IDX_IO_REC_DMA_CURROFS 0x34 /* PU:0x00000000 */ 90#define IDX_IO_REC_DMA_CURROFS 0x34 /* PU:0x00000000 */
88#define IDX_IO_REC_SOUNDFORMAT 0x36 /* PU:0x0000 */ 91#define IDX_IO_REC_SOUNDFORMAT 0x36 /* PU:0x0000 */
89 92
90/** hmm, what is this I/O area for? MPU401?? (after playback, recording, ???, timer) **/ 93/** hmm, what is this I/O area for? MPU401?? or external DAC via I2S?? (after playback, recording, ???, timer) **/
91#define IDX_IO_SOMETHING_FLAGS 0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init, PU:0x0000 */ 94#define IDX_IO_SOMETHING_FLAGS 0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init, PU:0x0000 */
92/* general */ 95/* general */
93#define IDX_IO_42H 0x42 /* PU:0x0001 */ 96#define IDX_IO_42H 0x42 /* PU:0x0001 */
@@ -107,7 +110,8 @@
107 #define IRQ_UNKNOWN2 0x0080 /* probably unused */ 110 #define IRQ_UNKNOWN2 0x0080 /* probably unused */
108#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */ 111#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
109#define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */ 112#define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */
110#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated; actually inhibits PCM playback!!! maybe power management?? */ 113#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */
114 #define IO_6A_PAUSE_PLAYBACK 0x0200 /* bit 9; sure, this pauses playback, but what the heck is this really about?? */
111#define IDX_IO_6CH 0x6C 115#define IDX_IO_6CH 0x6C
112#define IDX_IO_6EH 0x6E /* writing 0xffff returns 0x83fe */ 116#define IDX_IO_6EH 0x6E /* writing 0xffff returns 0x83fe */
113/* further I/O indices not saved/restored, so probably not used */ 117/* further I/O indices not saved/restored, so probably not used */
@@ -115,15 +119,25 @@
115 119
116/*** I/O 2 area port indices ***/ 120/*** I/O 2 area port indices ***/
117/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */ 121/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
122#define AZF_IO_SIZE_IO2 0x08
123#define AZF_IO_SIZE_IO2_PM 0x06
124
118#define IDX_IO2_LEGACY_ADDR 0x04 125#define IDX_IO2_LEGACY_ADDR 0x04
119 #define LEGACY_SOMETHING 0x01 /* OPL3?? */ 126 #define LEGACY_SOMETHING 0x01 /* OPL3?? */
120 #define LEGACY_JOY 0x08 127 #define LEGACY_JOY 0x08
121 128
129#define AZF_IO_SIZE_MPU 0x04
130#define AZF_IO_SIZE_MPU_PM 0x04
131
132#define AZF_IO_SIZE_SYNTH 0x08
133#define AZF_IO_SIZE_SYNTH_PM 0x06
122 134
123/*** mixer I/O area port indices ***/ 135/*** mixer I/O area port indices ***/
124/* (only 0x22 of 0x40 bytes saved/restored by Windows driver) 136/* (only 0x22 of 0x40 bytes saved/restored by Windows driver)
125 * generally spoken: AC97 register index = AZF3328 mixer reg index + 2 137 * UNFORTUNATELY azf3328 is NOT truly AC97 compliant: see main file intro */
126 * (in other words: AZF3328 NOT fully AC97 compliant) */ 138#define AZF_IO_SIZE_MIXER 0x40
139#define AZF_IO_SIZE_MIXER_PM 0x22
140
127 #define MIXER_VOLUME_RIGHT_MASK 0x001f 141 #define MIXER_VOLUME_RIGHT_MASK 0x001f
128 #define MIXER_VOLUME_LEFT_MASK 0x1f00 142 #define MIXER_VOLUME_LEFT_MASK 0x1f00
129 #define MIXER_MUTE_MASK 0x8000 143 #define MIXER_MUTE_MASK 0x8000
@@ -156,14 +170,14 @@
156#define IDX_MIXER_ADVCTL1 0x1e 170#define IDX_MIXER_ADVCTL1 0x1e
157 /* unlisted bits are unmodifiable */ 171 /* unlisted bits are unmodifiable */
158 #define MIXER_ADVCTL1_3DWIDTH_MASK 0x000e 172 #define MIXER_ADVCTL1_3DWIDTH_MASK 0x000e
159 #define MIXER_ADVCTL1_HIFI3D_MASK 0x0300 173 #define MIXER_ADVCTL1_HIFI3D_MASK 0x0300 /* yup, this is missing the high bit that official AC97 contains, plus it doesn't have linear bit value range behaviour but instead acts weirdly (possibly we're dealing with two *different* 3D settings here??) */
160#define IDX_MIXER_ADVCTL2 0x20 /* resembles AC97_GENERAL_PURPOSE reg! */ 174#define IDX_MIXER_ADVCTL2 0x20 /* subset of AC97_GENERAL_PURPOSE reg! */
161 /* unlisted bits are unmodifiable */ 175 /* unlisted bits are unmodifiable */
162 #define MIXER_ADVCTL2_BIT7 0x0080 /* WaveOut 3D Bypass? mutes WaveOut at LineOut */ 176 #define MIXER_ADVCTL2_LPBK 0x0080 /* Loopback mode -- Win driver: "WaveOut3DBypass"? mutes WaveOut at LineOut */
163 #define MIXER_ADVCTL2_BIT8 0x0100 /* is this Modem Out Select? */ 177 #define MIXER_ADVCTL2_MS 0x0100 /* Mic Select 0=Mic1, 1=Mic2 -- Win driver: "ModemOutSelect"?? */
164 #define MIXER_ADVCTL2_BIT9 0x0200 /* Mono Select Source? */ 178 #define MIXER_ADVCTL2_MIX 0x0200 /* Mono output select 0=Mix, 1=Mic; Win driver: "MonoSelectSource"?? */
165 #define MIXER_ADVCTL2_BIT13 0x2000 /* 3D enable? */ 179 #define MIXER_ADVCTL2_3D 0x2000 /* 3D Enhancement 1=on */
166 #define MIXER_ADVCTL2_BIT15 0x8000 /* unknown */ 180 #define MIXER_ADVCTL2_POP 0x8000 /* Pcm Out Path, 0=pre 3D, 1=post 3D */
167 181
168#define IDX_MIXER_SOMETHING30H 0x30 /* used, but unknown??? */ 182#define IDX_MIXER_SOMETHING30H 0x30 /* used, but unknown??? */
169 183
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 9ee07d4aac1e..c33642d8d9a1 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -44,7 +44,7 @@ MODULE_SUPPORTED_DEVICE("{{Brooktree,Bt878},"
44static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */ 44static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
45static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 45static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
46static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 46static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
47static int digital_rate[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* digital input rate */ 47static int digital_rate[SNDRV_CARDS]; /* digital input rate */
48static int load_all; /* allow to load the non-whitelisted cards */ 48static int load_all; /* allow to load the non-whitelisted cards */
49 49
50module_param_array(index, int, NULL, 0444); 50module_param_array(index, int, NULL, 0444);
@@ -781,10 +781,12 @@ static struct pci_device_id snd_bt87x_ids[] __devinitdata = {
781 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000), 781 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000),
782 /* Viewcast Osprey 200 */ 782 /* Viewcast Osprey 200 */
783 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), 783 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100),
784 /* AVerMedia Studio No. 103, 203, ...? */
785 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000),
786 /* Leadtek Winfast tv 2000xp delux */ 784 /* Leadtek Winfast tv 2000xp delux */
787 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000), 785 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000),
786 /* Voodoo TV 200 */
787 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, 32000),
788 /* AVerMedia Studio No. 103, 203, ...? */
789 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000),
788 { } 790 { }
789}; 791};
790MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); 792MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index c8131ea92ed6..9cb66c59f523 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -537,9 +537,9 @@
537#endif 537#endif
538 538
539#define ADC_MUX_MASK 0x0000000f //Mask for ADC Mux 539#define ADC_MUX_MASK 0x0000000f //Mask for ADC Mux
540#define ADC_MUX_PHONE 0x00000001 //Value to select TAD at ADC Mux (Not used)
540#define ADC_MUX_MIC 0x00000002 //Value to select Mic at ADC Mux 541#define ADC_MUX_MIC 0x00000002 //Value to select Mic at ADC Mux
541#define ADC_MUX_LINEIN 0x00000004 //Value to select LineIn at ADC Mux 542#define ADC_MUX_LINEIN 0x00000004 //Value to select LineIn at ADC Mux
542#define ADC_MUX_PHONE 0x00000001 //Value to select TAD at ADC Mux (Not used)
543#define ADC_MUX_AUX 0x00000008 //Value to select Aux at ADC Mux 543#define ADC_MUX_AUX 0x00000008 //Value to select Aux at ADC Mux
544 544
545#define SET_CHANNEL 0 /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */ 545#define SET_CHANNEL 0 /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
@@ -604,6 +604,8 @@ struct snd_ca0106 {
604 u32 spdif_bits[4]; /* s/pdif out setup */ 604 u32 spdif_bits[4]; /* s/pdif out setup */
605 int spdif_enable; 605 int spdif_enable;
606 int capture_source; 606 int capture_source;
607 int i2c_capture_source;
608 u8 i2c_capture_volume[4][2];
607 int capture_mic_line_in; 609 int capture_mic_line_in;
608 610
609 struct snd_dma_buffer buffer; 611 struct snd_dma_buffer buffer;
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index fd8bfebfbd54..59bf9bd02534 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -186,8 +186,8 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
186 /* New Audigy SE. Has a different DAC. */ 186 /* New Audigy SE. Has a different DAC. */
187 /* SB0570: 187 /* SB0570:
188 * CTRL:CA0106-DAT 188 * CTRL:CA0106-DAT
189 * ADC: WM8768GEDS 189 * ADC: WM8775EDS
190 * DAC: WM8775EDS 190 * DAC: WM8768GEDS
191 */ 191 */
192 { .serial = 0x100a1102, 192 { .serial = 0x100a1102,
193 .name = "Audigy SE [SB0570]", 193 .name = "Audigy SE [SB0570]",
@@ -195,9 +195,14 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
195 .i2c_adc = 1, 195 .i2c_adc = 1,
196 .spi_dac = 1 } , 196 .spi_dac = 1 } ,
197 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */ 197 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */
198 /* SB0438
199 * CTRL:CA0106-DAT
200 * ADC: WM8775SEDS
201 * DAC: CS4382-KQZ
202 */
198 { .serial = 0x10091462, 203 { .serial = 0x10091462,
199 .name = "MSI K8N Diamond MB [SB0438]", 204 .name = "MSI K8N Diamond MB [SB0438]",
200 .gpio_type = 1, 205 .gpio_type = 2,
201 .i2c_adc = 1 } , 206 .i2c_adc = 1 } ,
202 /* Shuttle XPC SD31P which has an onboard Creative Labs 207 /* Shuttle XPC SD31P which has an onboard Creative Labs
203 * Sound Blaster Live! 24-bit EAX 208 * Sound Blaster Live! 24-bit EAX
@@ -326,6 +331,7 @@ int snd_ca0106_spi_write(struct snd_ca0106 * emu,
326 return 0; 331 return 0;
327} 332}
328 333
334/* The ADC does not support i2c read, so only write is implemented */
329int snd_ca0106_i2c_write(struct snd_ca0106 *emu, 335int snd_ca0106_i2c_write(struct snd_ca0106 *emu,
330 u32 reg, 336 u32 reg,
331 u32 value) 337 u32 value)
@@ -340,6 +346,7 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu,
340 } 346 }
341 347
342 tmp = reg << 25 | value << 16; 348 tmp = reg << 25 | value << 16;
349 // snd_printk("I2C-write:reg=0x%x, value=0x%x\n", reg, value);
343 /* Not sure what this I2C channel controls. */ 350 /* Not sure what this I2C channel controls. */
344 /* snd_ca0106_ptr_write(emu, I2C_D0, 0, tmp); */ 351 /* snd_ca0106_ptr_write(emu, I2C_D0, 0, tmp); */
345 352
@@ -348,8 +355,9 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu,
348 355
349 for (retry = 0; retry < 10; retry++) { 356 for (retry = 0; retry < 10; retry++) {
350 /* Send the data to i2c */ 357 /* Send the data to i2c */
351 tmp = snd_ca0106_ptr_read(emu, I2C_A, 0); 358 //tmp = snd_ca0106_ptr_read(emu, I2C_A, 0);
352 tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK); 359 //tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK);
360 tmp = 0;
353 tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD); 361 tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD);
354 snd_ca0106_ptr_write(emu, I2C_A, 0, tmp); 362 snd_ca0106_ptr_write(emu, I2C_A, 0, tmp);
355 363
@@ -1181,7 +1189,7 @@ static unsigned int spi_dac_init[] = {
1181 0x02ff, 1189 0x02ff,
1182 0x0400, 1190 0x0400,
1183 0x0520, 1191 0x0520,
1184 0x0600, 1192 0x0620, /* Set 24 bit. Was 0x0600 */
1185 0x08ff, 1193 0x08ff,
1186 0x0aff, 1194 0x0aff,
1187 0x0cff, 1195 0x0cff,
@@ -1200,6 +1208,22 @@ static unsigned int spi_dac_init[] = {
1200 0x1400, 1208 0x1400,
1201}; 1209};
1202 1210
1211static unsigned int i2c_adc_init[][2] = {
1212 { 0x17, 0x00 }, /* Reset */
1213 { 0x07, 0x00 }, /* Timeout */
1214 { 0x0b, 0x22 }, /* Interface control */
1215 { 0x0c, 0x22 }, /* Master mode control */
1216 { 0x0d, 0x08 }, /* Powerdown control */
1217 { 0x0e, 0xcf }, /* Attenuation Left 0x01 = -103dB, 0xff = 24dB */
1218 { 0x0f, 0xcf }, /* Attenuation Right 0.5dB steps */
1219 { 0x10, 0x7b }, /* ALC Control 1 */
1220 { 0x11, 0x00 }, /* ALC Control 2 */
1221 { 0x12, 0x32 }, /* ALC Control 3 */
1222 { 0x13, 0x00 }, /* Noise gate control */
1223 { 0x14, 0xa6 }, /* Limiter control */
1224 { 0x15, ADC_MUX_LINEIN }, /* ADC Mixer control */
1225};
1226
1203static int __devinit snd_ca0106_create(struct snd_card *card, 1227static int __devinit snd_ca0106_create(struct snd_card *card,
1204 struct pci_dev *pci, 1228 struct pci_dev *pci,
1205 struct snd_ca0106 **rchip) 1229 struct snd_ca0106 **rchip)
@@ -1361,7 +1385,12 @@ static int __devinit snd_ca0106_create(struct snd_card *card,
1361 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC, Line in, TAD in, AUX in */ 1385 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC, Line in, TAD in, AUX in */
1362 chip->capture_source = 3; /* Set CAPTURE_SOURCE */ 1386 chip->capture_source = 3; /* Set CAPTURE_SOURCE */
1363 1387
1364 if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */ 1388 if (chip->details->gpio_type == 2) { /* The SB0438 use GPIO differently. */
1389 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */
1390 outl(0x0, chip->port+GPIO);
1391 //outl(0x00f0e000, chip->port+GPIO); /* Analog */
1392 outl(0x005f5301, chip->port+GPIO); /* Analog */
1393 } else if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */
1365 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ 1394 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */
1366 outl(0x0, chip->port+GPIO); 1395 outl(0x0, chip->port+GPIO);
1367 //outl(0x00f0e000, chip->port+GPIO); /* Analog */ 1396 //outl(0x00f0e000, chip->port+GPIO); /* Analog */
@@ -1379,7 +1408,19 @@ static int __devinit snd_ca0106_create(struct snd_card *card,
1379 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */ 1408 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */
1380 1409
1381 if (chip->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */ 1410 if (chip->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */
1382 snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */ 1411 int size, n;
1412
1413 size = ARRAY_SIZE(i2c_adc_init);
1414 //snd_printk("I2C:array size=0x%x\n", size);
1415 for (n=0; n < size; n++) {
1416 snd_ca0106_i2c_write(chip, i2c_adc_init[n][0], i2c_adc_init[n][1]);
1417 }
1418 for (n=0; n < 4; n++) {
1419 chip->i2c_capture_volume[n][0]= 0xcf;
1420 chip->i2c_capture_volume[n][1]= 0xcf;
1421 }
1422 chip->i2c_capture_source=2; /* Line in */
1423 //snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */
1383 } 1424 }
1384 if (chip->details->spi_dac == 1) { /* The SB0570 use SPI to control DAC. */ 1425 if (chip->details->spi_dac == 1) { /* The SB0570 use SPI to control DAC. */
1385 int size, n; 1426 int size, n;
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 06fe055674fb..146eed70dce6 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -171,6 +171,76 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
171 return change; 171 return change;
172} 172}
173 173
174static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
175 struct snd_ctl_elem_info *uinfo)
176{
177 static char *texts[6] = {
178 "Phone", "Mic", "Line in", "Aux"
179 };
180
181 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
182 uinfo->count = 1;
183 uinfo->value.enumerated.items = 4;
184 if (uinfo->value.enumerated.item > 3)
185 uinfo->value.enumerated.item = 3;
186 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
187 return 0;
188}
189
190static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
191 struct snd_ctl_elem_value *ucontrol)
192{
193 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
194
195 ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
196 return 0;
197}
198
199static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
200 struct snd_ctl_elem_value *ucontrol)
201{
202 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
203 unsigned int source_id;
204 unsigned int ngain, ogain;
205 int change = 0;
206 u32 source;
207 /* If the capture source has changed,
208 * update the capture volume from the cached value
209 * for the particular source.
210 */
211 source_id = ucontrol->value.enumerated.item[0] ;
212 change = (emu->i2c_capture_source != source_id);
213 if (change) {
214 snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
215 ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
216 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
217 if (ngain != ogain)
218 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff));
219 ngain = emu->i2c_capture_volume[source_id][1]; /* Left */
220 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Left */
221 if (ngain != ogain)
222 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
223 source = 1 << source_id;
224 snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
225 emu->i2c_capture_source = source_id;
226 }
227 return change;
228}
229
230static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol,
231 struct snd_ctl_elem_info *uinfo)
232{
233 static char *texts[2] = { "Side out", "Line in" };
234
235 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
236 uinfo->count = 1;
237 uinfo->value.enumerated.items = 2;
238 if (uinfo->value.enumerated.item > 1)
239 uinfo->value.enumerated.item = 1;
240 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
241 return 0;
242}
243
174static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol, 244static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol,
175 struct snd_ctl_elem_info *uinfo) 245 struct snd_ctl_elem_info *uinfo)
176{ 246{
@@ -207,16 +277,16 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
207 if (change) { 277 if (change) {
208 emu->capture_mic_line_in = val; 278 emu->capture_mic_line_in = val;
209 if (val) { 279 if (val) {
210 snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_PHONE); /* Mute input */ 280 //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
211 tmp = inl(emu->port+GPIO) & ~0x400; 281 tmp = inl(emu->port+GPIO) & ~0x400;
212 tmp = tmp | 0x400; 282 tmp = tmp | 0x400;
213 outl(tmp, emu->port+GPIO); 283 outl(tmp, emu->port+GPIO);
214 snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); 284 //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC);
215 } else { 285 } else {
216 snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_PHONE); /* Mute input */ 286 //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
217 tmp = inl(emu->port+GPIO) & ~0x400; 287 tmp = inl(emu->port+GPIO) & ~0x400;
218 outl(tmp, emu->port+GPIO); 288 outl(tmp, emu->port+GPIO);
219 snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); 289 //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN);
220 } 290 }
221 } 291 }
222 return change; 292 return change;
@@ -225,12 +295,22 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
225static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in __devinitdata = 295static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in __devinitdata =
226{ 296{
227 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 297 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
228 .name = "Mic/Line in Capture", 298 .name = "Shared Mic/Line in Capture Switch",
229 .info = snd_ca0106_capture_mic_line_in_info, 299 .info = snd_ca0106_capture_mic_line_in_info,
230 .get = snd_ca0106_capture_mic_line_in_get, 300 .get = snd_ca0106_capture_mic_line_in_get,
231 .put = snd_ca0106_capture_mic_line_in_put 301 .put = snd_ca0106_capture_mic_line_in_put
232}; 302};
233 303
304static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out __devinitdata =
305{
306 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
307 .name = "Shared Line in/Side out Capture Switch",
308 .info = snd_ca0106_capture_line_in_side_out_info,
309 .get = snd_ca0106_capture_mic_line_in_get,
310 .put = snd_ca0106_capture_mic_line_in_put
311};
312
313
234static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol, 314static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
235 struct snd_ctl_elem_info *uinfo) 315 struct snd_ctl_elem_info *uinfo)
236{ 316{
@@ -329,15 +409,81 @@ static int snd_ca0106_volume_put(struct snd_kcontrol *kcontrol,
329 return 1; 409 return 1;
330} 410}
331 411
412static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol,
413 struct snd_ctl_elem_info *uinfo)
414{
415 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
416 uinfo->count = 2;
417 uinfo->value.integer.min = 0;
418 uinfo->value.integer.max = 255;
419 return 0;
420}
421
422static int snd_ca0106_i2c_volume_get(struct snd_kcontrol *kcontrol,
423 struct snd_ctl_elem_value *ucontrol)
424{
425 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
426 int source_id;
427
428 source_id = kcontrol->private_value;
429
430 ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
431 ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
432 return 0;
433}
434
435static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
436 struct snd_ctl_elem_value *ucontrol)
437{
438 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
439 unsigned int ogain;
440 unsigned int ngain;
441 int source_id;
442 int change = 0;
443
444 source_id = kcontrol->private_value;
445 ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
446 ngain = ucontrol->value.integer.value[0];
447 if (ngain > 0xff)
448 return 0;
449 if (ogain != ngain) {
450 if (emu->i2c_capture_source == source_id)
451 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
452 emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0];
453 change = 1;
454 }
455 ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
456 ngain = ucontrol->value.integer.value[1];
457 if (ngain > 0xff)
458 return 0;
459 if (ogain != ngain) {
460 if (emu->i2c_capture_source == source_id)
461 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
462 emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1];
463 change = 1;
464 }
465
466 return change;
467}
468
332#define CA_VOLUME(xname,chid,reg) \ 469#define CA_VOLUME(xname,chid,reg) \
333{ \ 470{ \
334 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 471 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
335 .info = snd_ca0106_volume_info, \ 472 .info = snd_ca0106_volume_info, \
336 .get = snd_ca0106_volume_get, \ 473 .get = snd_ca0106_volume_get, \
337 .put = snd_ca0106_volume_put, \ 474 .put = snd_ca0106_volume_put, \
338 .private_value = ((chid) << 8) | (reg) \ 475 .private_value = ((chid) << 8) | (reg) \
339} 476}
340 477
478#define I2C_VOLUME(xname,chid) \
479{ \
480 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
481 .info = snd_ca0106_i2c_volume_info, \
482 .get = snd_ca0106_i2c_volume_get, \
483 .put = snd_ca0106_i2c_volume_put, \
484 .private_value = chid \
485}
486
341 487
342static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = { 488static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
343 CA_VOLUME("Analog Front Playback Volume", 489 CA_VOLUME("Analog Front Playback Volume",
@@ -361,6 +507,11 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
361 CA_VOLUME("CAPTURE feedback Playback Volume", 507 CA_VOLUME("CAPTURE feedback Playback Volume",
362 1, CAPTURE_CONTROL), 508 1, CAPTURE_CONTROL),
363 509
510 I2C_VOLUME("Phone Capture Volume", 0),
511 I2C_VOLUME("Mic Capture Volume", 1),
512 I2C_VOLUME("Line in Capture Volume", 2),
513 I2C_VOLUME("Aux Capture Volume", 3),
514
364 { 515 {
365 .access = SNDRV_CTL_ELEM_ACCESS_READ, 516 .access = SNDRV_CTL_ELEM_ACCESS_READ,
366 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 517 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -378,12 +529,19 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
378 }, 529 },
379 { 530 {
380 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
381 .name = "Capture Source", 532 .name = "Digital Capture Source",
382 .info = snd_ca0106_capture_source_info, 533 .info = snd_ca0106_capture_source_info,
383 .get = snd_ca0106_capture_source_get, 534 .get = snd_ca0106_capture_source_get,
384 .put = snd_ca0106_capture_source_put 535 .put = snd_ca0106_capture_source_put
385 }, 536 },
386 { 537 {
538 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
539 .name = "Capture Source",
540 .info = snd_ca0106_i2c_capture_source_info,
541 .get = snd_ca0106_i2c_capture_source_get,
542 .put = snd_ca0106_i2c_capture_source_put
543 },
544 {
387 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 545 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
388 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 546 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
389 .count = 4, 547 .count = 4,
@@ -477,7 +635,10 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
477 return err; 635 return err;
478 } 636 }
479 if (emu->details->i2c_adc == 1) { 637 if (emu->details->i2c_adc == 1) {
480 err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu)); 638 if (emu->details->gpio_type == 1)
639 err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
640 else /* gpio_type == 2 */
641 err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out, emu));
481 if (err < 0) 642 if (err < 0)
482 return err; 643 return err;
483 } 644 }
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
index 63757273bfb7..75ca421eb3a1 100644
--- a/sound/pci/ca0106/ca0106_proc.c
+++ b/sound/pci/ca0106/ca0106_proc.c
@@ -431,33 +431,30 @@ int __devinit snd_ca0106_proc_init(struct snd_ca0106 * emu)
431 struct snd_info_entry *entry; 431 struct snd_info_entry *entry;
432 432
433 if(! snd_card_proc_new(emu->card, "iec958", &entry)) 433 if(! snd_card_proc_new(emu->card, "iec958", &entry))
434 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_iec958); 434 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_iec958);
435 if(! snd_card_proc_new(emu->card, "ca0106_reg32", &entry)) { 435 if(! snd_card_proc_new(emu->card, "ca0106_reg32", &entry)) {
436 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read32); 436 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read32);
437 entry->c.text.write_size = 64;
438 entry->c.text.write = snd_ca0106_proc_reg_write32; 437 entry->c.text.write = snd_ca0106_proc_reg_write32;
439 entry->mode |= S_IWUSR; 438 entry->mode |= S_IWUSR;
440 } 439 }
441 if(! snd_card_proc_new(emu->card, "ca0106_reg16", &entry)) 440 if(! snd_card_proc_new(emu->card, "ca0106_reg16", &entry))
442 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read16); 441 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read16);
443 if(! snd_card_proc_new(emu->card, "ca0106_reg8", &entry)) 442 if(! snd_card_proc_new(emu->card, "ca0106_reg8", &entry))
444 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read8); 443 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read8);
445 if(! snd_card_proc_new(emu->card, "ca0106_regs1", &entry)) { 444 if(! snd_card_proc_new(emu->card, "ca0106_regs1", &entry)) {
446 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read1); 445 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read1);
447 entry->c.text.write_size = 64;
448 entry->c.text.write = snd_ca0106_proc_reg_write; 446 entry->c.text.write = snd_ca0106_proc_reg_write;
449 entry->mode |= S_IWUSR; 447 entry->mode |= S_IWUSR;
450// entry->private_data = emu; 448// entry->private_data = emu;
451 } 449 }
452 if(! snd_card_proc_new(emu->card, "ca0106_i2c", &entry)) { 450 if(! snd_card_proc_new(emu->card, "ca0106_i2c", &entry)) {
453 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_i2c_write); 451 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_i2c_write);
454 entry->c.text.write_size = 64;
455 entry->c.text.write = snd_ca0106_proc_i2c_write; 452 entry->c.text.write = snd_ca0106_proc_i2c_write;
456 entry->mode |= S_IWUSR; 453 entry->mode |= S_IWUSR;
457// entry->private_data = emu; 454// entry->private_data = emu;
458 } 455 }
459 if(! snd_card_proc_new(emu->card, "ca0106_regs2", &entry)) 456 if(! snd_card_proc_new(emu->card, "ca0106_regs2", &entry))
460 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read2); 457 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read2);
461 return 0; 458 return 0;
462} 459}
463 460
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index e5ce2dabd081..0938c158b5c9 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -2121,7 +2121,7 @@ static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = {
2121 CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7), 2121 CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7),
2122 CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7), 2122 CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7),
2123 CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0), 2123 CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0),
2124 CMIPCI_DOUBLE("PC Speaker Playnack Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0), 2124 CMIPCI_DOUBLE("PC Speaker Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0),
2125 CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0), 2125 CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0),
2126}; 2126};
2127 2127
@@ -2602,7 +2602,7 @@ static void __devinit snd_cmipci_proc_init(struct cmipci *cm)
2602 struct snd_info_entry *entry; 2602 struct snd_info_entry *entry;
2603 2603
2604 if (! snd_card_proc_new(cm->card, "cmipci", &entry)) 2604 if (! snd_card_proc_new(cm->card, "cmipci", &entry))
2605 snd_info_set_text_ops(entry, cm, 1024, snd_cmipci_proc_read); 2605 snd_info_set_text_ops(entry, cm, snd_cmipci_proc_read);
2606} 2606}
2607#else /* !CONFIG_PROC_FS */ 2607#else /* !CONFIG_PROC_FS */
2608static inline void snd_cmipci_proc_init(struct cmipci *cm) {} 2608static inline void snd_cmipci_proc_init(struct cmipci *cm) {}
@@ -2932,7 +2932,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
2932 } 2932 }
2933 2933
2934 integrated_midi = snd_cmipci_read_b(cm, CM_REG_MPU_PCI) != 0xff; 2934 integrated_midi = snd_cmipci_read_b(cm, CM_REG_MPU_PCI) != 0xff;
2935 if (integrated_midi) 2935 if (integrated_midi && mpu_port[dev] == 1)
2936 iomidi = cm->iobase + CM_REG_MPU_PCI; 2936 iomidi = cm->iobase + CM_REG_MPU_PCI;
2937 else { 2937 else {
2938 iomidi = mpu_port[dev]; 2938 iomidi = mpu_port[dev];
@@ -2981,7 +2981,9 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
2981 2981
2982 if (iomidi > 0) { 2982 if (iomidi > 0) {
2983 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, 2983 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
2984 iomidi, integrated_midi, 2984 iomidi,
2985 (integrated_midi ?
2986 MPU401_INFO_INTEGRATED : 0),
2985 cm->irq, 0, &cm->rmidi)) < 0) { 2987 cm->irq, 0, &cm->rmidi)) < 0) {
2986 printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi); 2988 printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi);
2987 } 2989 }
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index b3c94d83450a..e77a4ce314b7 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1184,7 +1184,7 @@ static void __devinit snd_cs4281_proc_init(struct cs4281 * chip)
1184 struct snd_info_entry *entry; 1184 struct snd_info_entry *entry;
1185 1185
1186 if (! snd_card_proc_new(chip->card, "cs4281", &entry)) 1186 if (! snd_card_proc_new(chip->card, "cs4281", &entry))
1187 snd_info_set_text_ops(entry, chip, 1024, snd_cs4281_proc_read); 1187 snd_info_set_text_ops(entry, chip, snd_cs4281_proc_read);
1188 if (! snd_card_proc_new(chip->card, "cs4281_BA0", &entry)) { 1188 if (! snd_card_proc_new(chip->card, "cs4281_BA0", &entry)) {
1189 entry->content = SNDRV_INFO_CONTENT_DATA; 1189 entry->content = SNDRV_INFO_CONTENT_DATA;
1190 entry->private_data = chip; 1190 entry->private_data = chip;
@@ -1379,6 +1379,13 @@ static int __devinit snd_cs4281_create(struct snd_card *card,
1379 chip->ba0_addr = pci_resource_start(pci, 0); 1379 chip->ba0_addr = pci_resource_start(pci, 0);
1380 chip->ba1_addr = pci_resource_start(pci, 1); 1380 chip->ba1_addr = pci_resource_start(pci, 1);
1381 1381
1382 chip->ba0 = ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0));
1383 chip->ba1 = ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1));
1384 if (!chip->ba0 || !chip->ba1) {
1385 snd_cs4281_free(chip);
1386 return -ENOMEM;
1387 }
1388
1382 if (request_irq(pci->irq, snd_cs4281_interrupt, SA_INTERRUPT|SA_SHIRQ, 1389 if (request_irq(pci->irq, snd_cs4281_interrupt, SA_INTERRUPT|SA_SHIRQ,
1383 "CS4281", chip)) { 1390 "CS4281", chip)) {
1384 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1391 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
@@ -1387,13 +1394,6 @@ static int __devinit snd_cs4281_create(struct snd_card *card,
1387 } 1394 }
1388 chip->irq = pci->irq; 1395 chip->irq = pci->irq;
1389 1396
1390 chip->ba0 = ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0));
1391 chip->ba1 = ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1));
1392 if (!chip->ba0 || !chip->ba1) {
1393 snd_cs4281_free(chip);
1394 return -ENOMEM;
1395 }
1396
1397 tmp = snd_cs4281_chip_init(chip); 1397 tmp = snd_cs4281_chip_init(chip);
1398 if (tmp) { 1398 if (tmp) {
1399 snd_cs4281_free(chip); 1399 snd_cs4281_free(chip);
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 848d772ae3c6..772dc52bfeb2 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -48,8 +48,8 @@ MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,Sound Fusion (CS4280)},"
48static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 48static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
49static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 49static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
50static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 50static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
51static int external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 51static int external_amp[SNDRV_CARDS];
52static int thinkpad[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 52static int thinkpad[SNDRV_CARDS];
53static int mmap_valid[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; 53static int mmap_valid[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
54 54
55module_param_array(index, int, NULL, 0444); 55module_param_array(index, int, NULL, 0444);
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 69dbf542a6de..5c2114439204 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -2877,14 +2877,15 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
2877 if (chip->region.idx[0].resource) 2877 if (chip->region.idx[0].resource)
2878 snd_cs46xx_hw_stop(chip); 2878 snd_cs46xx_hw_stop(chip);
2879 2879
2880 if (chip->irq >= 0)
2881 free_irq(chip->irq, chip);
2882
2880 for (idx = 0; idx < 5; idx++) { 2883 for (idx = 0; idx < 5; idx++) {
2881 struct snd_cs46xx_region *region = &chip->region.idx[idx]; 2884 struct snd_cs46xx_region *region = &chip->region.idx[idx];
2882 if (region->remap_addr) 2885 if (region->remap_addr)
2883 iounmap(region->remap_addr); 2886 iounmap(region->remap_addr);
2884 release_and_free_resource(region->resource); 2887 release_and_free_resource(region->resource);
2885 } 2888 }
2886 if (chip->irq >= 0)
2887 free_irq(chip->irq, chip);
2888 2889
2889 if (chip->active_ctrl) 2890 if (chip->active_ctrl)
2890 chip->active_ctrl(chip, -chip->amplifier); 2891 chip->active_ctrl(chip, -chip->amplifier);
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index f407d2a5ce3b..5c9711c0265c 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -767,7 +767,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
767 if ((entry = snd_info_create_card_entry(card, "dsp", card->proc_root)) != NULL) { 767 if ((entry = snd_info_create_card_entry(card, "dsp", card->proc_root)) != NULL) {
768 entry->content = SNDRV_INFO_CONTENT_TEXT; 768 entry->content = SNDRV_INFO_CONTENT_TEXT;
769 entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; 769 entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
770 entry->c.text.read_size = 512;
771 770
772 if (snd_info_register(entry) < 0) { 771 if (snd_info_register(entry) < 0) {
773 snd_info_free_entry(entry); 772 snd_info_free_entry(entry);
@@ -784,7 +783,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
784 entry->content = SNDRV_INFO_CONTENT_TEXT; 783 entry->content = SNDRV_INFO_CONTENT_TEXT;
785 entry->private_data = chip; 784 entry->private_data = chip;
786 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 785 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
787 entry->c.text.read_size = 512;
788 entry->c.text.read = cs46xx_dsp_proc_symbol_table_read; 786 entry->c.text.read = cs46xx_dsp_proc_symbol_table_read;
789 if (snd_info_register(entry) < 0) { 787 if (snd_info_register(entry) < 0) {
790 snd_info_free_entry(entry); 788 snd_info_free_entry(entry);
@@ -797,7 +795,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
797 entry->content = SNDRV_INFO_CONTENT_TEXT; 795 entry->content = SNDRV_INFO_CONTENT_TEXT;
798 entry->private_data = chip; 796 entry->private_data = chip;
799 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 797 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
800 entry->c.text.read_size = 512;
801 entry->c.text.read = cs46xx_dsp_proc_modules_read; 798 entry->c.text.read = cs46xx_dsp_proc_modules_read;
802 if (snd_info_register(entry) < 0) { 799 if (snd_info_register(entry) < 0) {
803 snd_info_free_entry(entry); 800 snd_info_free_entry(entry);
@@ -810,7 +807,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
810 entry->content = SNDRV_INFO_CONTENT_TEXT; 807 entry->content = SNDRV_INFO_CONTENT_TEXT;
811 entry->private_data = chip; 808 entry->private_data = chip;
812 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 809 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
813 entry->c.text.read_size = 512;
814 entry->c.text.read = cs46xx_dsp_proc_parameter_dump_read; 810 entry->c.text.read = cs46xx_dsp_proc_parameter_dump_read;
815 if (snd_info_register(entry) < 0) { 811 if (snd_info_register(entry) < 0) {
816 snd_info_free_entry(entry); 812 snd_info_free_entry(entry);
@@ -823,7 +819,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
823 entry->content = SNDRV_INFO_CONTENT_TEXT; 819 entry->content = SNDRV_INFO_CONTENT_TEXT;
824 entry->private_data = chip; 820 entry->private_data = chip;
825 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 821 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
826 entry->c.text.read_size = 512;
827 entry->c.text.read = cs46xx_dsp_proc_sample_dump_read; 822 entry->c.text.read = cs46xx_dsp_proc_sample_dump_read;
828 if (snd_info_register(entry) < 0) { 823 if (snd_info_register(entry) < 0) {
829 snd_info_free_entry(entry); 824 snd_info_free_entry(entry);
@@ -836,7 +831,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
836 entry->content = SNDRV_INFO_CONTENT_TEXT; 831 entry->content = SNDRV_INFO_CONTENT_TEXT;
837 entry->private_data = chip; 832 entry->private_data = chip;
838 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 833 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
839 entry->c.text.read_size = 512;
840 entry->c.text.read = cs46xx_dsp_proc_task_tree_read; 834 entry->c.text.read = cs46xx_dsp_proc_task_tree_read;
841 if (snd_info_register(entry) < 0) { 835 if (snd_info_register(entry) < 0) {
842 snd_info_free_entry(entry); 836 snd_info_free_entry(entry);
@@ -849,7 +843,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
849 entry->content = SNDRV_INFO_CONTENT_TEXT; 843 entry->content = SNDRV_INFO_CONTENT_TEXT;
850 entry->private_data = chip; 844 entry->private_data = chip;
851 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 845 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
852 entry->c.text.read_size = 1024;
853 entry->c.text.read = cs46xx_dsp_proc_scb_read; 846 entry->c.text.read = cs46xx_dsp_proc_scb_read;
854 if (snd_info_register(entry) < 0) { 847 if (snd_info_register(entry) < 0) {
855 snd_info_free_entry(entry); 848 snd_info_free_entry(entry);
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index 2c4ee45fe10c..3844d18af19c 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -267,7 +267,6 @@ void cs46xx_dsp_proc_register_scb_desc (struct snd_cs46xx *chip,
267 entry->private_data = scb_info; 267 entry->private_data = scb_info;
268 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 268 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
269 269
270 entry->c.text.read_size = 512;
271 entry->c.text.read = cs46xx_dsp_proc_scb_info_read; 270 entry->c.text.read = cs46xx_dsp_proc_scb_info_read;
272 271
273 if (snd_info_register(entry) < 0) { 272 if (snd_info_register(entry) < 0) {
diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile
index 08d8ee6547d3..2911a8adc1f2 100644
--- a/sound/pci/cs5535audio/Makefile
+++ b/sound/pci/cs5535audio/Makefile
@@ -4,5 +4,9 @@
4 4
5snd-cs5535audio-objs := cs5535audio.o cs5535audio_pcm.o 5snd-cs5535audio-objs := cs5535audio.o cs5535audio_pcm.o
6 6
7ifdef CONFIG_PM
8snd-cs5535audio-objs += cs5535audio_pm.o
9endif
10
7# Toplevel Module Dependency 11# Toplevel Module Dependency
8obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o 12obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 2c1213a35dcc..91c18a11fe87 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Driver for audio on multifunction CS5535 companion device 2 * Driver for audio on multifunction CS5535/6 companion device
3 * Copyright (C) Jaya Kumar 3 * Copyright (C) Jaya Kumar
4 * 4 *
5 * Based on Jaroslav Kysela and Takashi Iwai's examples. 5 * Based on Jaroslav Kysela and Takashi Iwai's examples.
@@ -40,16 +40,36 @@
40 40
41#define DRIVER_NAME "cs5535audio" 41#define DRIVER_NAME "cs5535audio"
42 42
43static char *ac97_quirk;
44module_param(ac97_quirk, charp, 0444);
45MODULE_PARM_DESC(ac97_quirk, "AC'97 board specific workarounds.");
46
47static struct ac97_quirk ac97_quirks[] __devinitdata = {
48#if 0 /* Not yet confirmed if all 5536 boards are HP only */
49 {
50 .subvendor = PCI_VENDOR_ID_AMD,
51 .subdevice = PCI_DEVICE_ID_AMD_CS5536_AUDIO,
52 .name = "AMD RDK",
53 .type = AC97_TUNE_HP_ONLY
54 },
55#endif
56 {}
57};
43 58
44static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 59static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
45static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 60static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
46static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 61static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
47 62
63module_param_array(index, int, NULL, 0444);
64MODULE_PARM_DESC(index, "Index value for " DRIVER_NAME);
65module_param_array(id, charp, NULL, 0444);
66MODULE_PARM_DESC(id, "ID string for " DRIVER_NAME);
67module_param_array(enable, bool, NULL, 0444);
68MODULE_PARM_DESC(enable, "Enable " DRIVER_NAME);
69
48static struct pci_device_id snd_cs5535audio_ids[] __devinitdata = { 70static struct pci_device_id snd_cs5535audio_ids[] __devinitdata = {
49 { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO, 71 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO) },
50 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, 72 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO) },
51 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO,
52 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
53 {} 73 {}
54}; 74};
55 75
@@ -90,7 +110,8 @@ static unsigned short snd_cs5535audio_codec_read(struct cs5535audio *cs5535au,
90 udelay(1); 110 udelay(1);
91 } while (--timeout); 111 } while (--timeout);
92 if (!timeout) 112 if (!timeout)
93 snd_printk(KERN_ERR "Failure reading cs5535 codec\n"); 113 snd_printk(KERN_ERR "Failure reading codec reg 0x%x,"
114 "Last value=0x%x\n", reg, val);
94 115
95 return (unsigned short) val; 116 return (unsigned short) val;
96} 117}
@@ -148,6 +169,8 @@ static int snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
148 return err; 169 return err;
149 } 170 }
150 171
172 snd_ac97_tune_hardware(cs5535au->ac97, ac97_quirks, ac97_quirk);
173
151 return 0; 174 return 0;
152} 175}
153 176
@@ -347,6 +370,8 @@ static int __devinit snd_cs5535audio_probe(struct pci_dev *pci,
347 if ((err = snd_cs5535audio_create(card, pci, &cs5535au)) < 0) 370 if ((err = snd_cs5535audio_create(card, pci, &cs5535au)) < 0)
348 goto probefail_out; 371 goto probefail_out;
349 372
373 card->private_data = cs5535au;
374
350 if ((err = snd_cs5535audio_mixer(cs5535au)) < 0) 375 if ((err = snd_cs5535audio_mixer(cs5535au)) < 0)
351 goto probefail_out; 376 goto probefail_out;
352 377
@@ -383,6 +408,10 @@ static struct pci_driver driver = {
383 .id_table = snd_cs5535audio_ids, 408 .id_table = snd_cs5535audio_ids,
384 .probe = snd_cs5535audio_probe, 409 .probe = snd_cs5535audio_probe,
385 .remove = __devexit_p(snd_cs5535audio_remove), 410 .remove = __devexit_p(snd_cs5535audio_remove),
411#ifdef CONFIG_PM
412 .suspend = snd_cs5535audio_suspend,
413 .resume = snd_cs5535audio_resume,
414#endif
386}; 415};
387 416
388static int __init alsa_card_cs5535audio_init(void) 417static int __init alsa_card_cs5535audio_init(void)
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index 5e55a1a1ed65..4fd1f31a6cf9 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -74,6 +74,8 @@
74#define PRM_RDY_STS 0x00800000 74#define PRM_RDY_STS 0x00800000
75#define ACC_CODEC_CNTL_WR_CMD (~0x80000000) 75#define ACC_CODEC_CNTL_WR_CMD (~0x80000000)
76#define ACC_CODEC_CNTL_RD_CMD 0x80000000 76#define ACC_CODEC_CNTL_RD_CMD 0x80000000
77#define ACC_CODEC_CNTL_LNK_SHUTDOWN 0x00040000
78#define ACC_CODEC_CNTL_LNK_WRM_RST 0x00020000
77#define PRD_JMP 0x2000 79#define PRD_JMP 0x2000
78#define PRD_EOP 0x4000 80#define PRD_EOP 0x4000
79#define PRD_EOT 0x8000 81#define PRD_EOT 0x8000
@@ -88,6 +90,7 @@ struct cs5535audio_dma_ops {
88 void (*disable_dma)(struct cs5535audio *cs5535au); 90 void (*disable_dma)(struct cs5535audio *cs5535au);
89 void (*pause_dma)(struct cs5535audio *cs5535au); 91 void (*pause_dma)(struct cs5535audio *cs5535au);
90 void (*setup_prd)(struct cs5535audio *cs5535au, u32 prd_addr); 92 void (*setup_prd)(struct cs5535audio *cs5535au, u32 prd_addr);
93 u32 (*read_prd)(struct cs5535audio *cs5535au);
91 u32 (*read_dma_pntr)(struct cs5535audio *cs5535au); 94 u32 (*read_dma_pntr)(struct cs5535audio *cs5535au);
92}; 95};
93 96
@@ -103,11 +106,14 @@ struct cs5535audio_dma {
103 struct snd_pcm_substream *substream; 106 struct snd_pcm_substream *substream;
104 unsigned int buf_addr, buf_bytes; 107 unsigned int buf_addr, buf_bytes;
105 unsigned int period_bytes, periods; 108 unsigned int period_bytes, periods;
109 int suspended;
110 u32 saved_prd;
106}; 111};
107 112
108struct cs5535audio { 113struct cs5535audio {
109 struct snd_card *card; 114 struct snd_card *card;
110 struct snd_ac97 *ac97; 115 struct snd_ac97 *ac97;
116 struct snd_pcm *pcm;
111 int irq; 117 int irq;
112 struct pci_dev *pci; 118 struct pci_dev *pci;
113 unsigned long port; 119 unsigned long port;
@@ -117,6 +123,8 @@ struct cs5535audio {
117 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS]; 123 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS];
118}; 124};
119 125
126int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state);
127int snd_cs5535audio_resume(struct pci_dev *pci);
120int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio); 128int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio);
121 129
122#endif /* __SOUND_CS5535AUDIO_H */ 130#endif /* __SOUND_CS5535AUDIO_H */
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index 60bb82b2ff47..f0a48693d687 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -43,7 +43,8 @@ static struct snd_pcm_hardware snd_cs5535audio_playback =
43 SNDRV_PCM_INFO_BLOCK_TRANSFER | 43 SNDRV_PCM_INFO_BLOCK_TRANSFER |
44 SNDRV_PCM_INFO_MMAP_VALID | 44 SNDRV_PCM_INFO_MMAP_VALID |
45 SNDRV_PCM_INFO_PAUSE | 45 SNDRV_PCM_INFO_PAUSE |
46 SNDRV_PCM_INFO_SYNC_START 46 SNDRV_PCM_INFO_SYNC_START |
47 SNDRV_PCM_INFO_RESUME
47 ), 48 ),
48 .formats = ( 49 .formats = (
49 SNDRV_PCM_FMTBIT_S16_LE 50 SNDRV_PCM_FMTBIT_S16_LE
@@ -193,6 +194,11 @@ static void cs5535audio_playback_setup_prd(struct cs5535audio *cs5535au,
193 cs_writel(cs5535au, ACC_BM0_PRD, prd_addr); 194 cs_writel(cs5535au, ACC_BM0_PRD, prd_addr);
194} 195}
195 196
197static u32 cs5535audio_playback_read_prd(struct cs5535audio *cs5535au)
198{
199 return cs_readl(cs5535au, ACC_BM0_PRD);
200}
201
196static u32 cs5535audio_playback_read_dma_pntr(struct cs5535audio *cs5535au) 202static u32 cs5535audio_playback_read_dma_pntr(struct cs5535audio *cs5535au)
197{ 203{
198 return cs_readl(cs5535au, ACC_BM0_PNTR); 204 return cs_readl(cs5535au, ACC_BM0_PNTR);
@@ -219,6 +225,11 @@ static void cs5535audio_capture_setup_prd(struct cs5535audio *cs5535au,
219 cs_writel(cs5535au, ACC_BM1_PRD, prd_addr); 225 cs_writel(cs5535au, ACC_BM1_PRD, prd_addr);
220} 226}
221 227
228static u32 cs5535audio_capture_read_prd(struct cs5535audio *cs5535au)
229{
230 return cs_readl(cs5535au, ACC_BM1_PRD);
231}
232
222static u32 cs5535audio_capture_read_dma_pntr(struct cs5535audio *cs5535au) 233static u32 cs5535audio_capture_read_dma_pntr(struct cs5535audio *cs5535au)
223{ 234{
224 return cs_readl(cs5535au, ACC_BM1_PNTR); 235 return cs_readl(cs5535au, ACC_BM1_PNTR);
@@ -285,9 +296,17 @@ static int snd_cs5535audio_trigger(struct snd_pcm_substream *substream, int cmd)
285 case SNDRV_PCM_TRIGGER_START: 296 case SNDRV_PCM_TRIGGER_START:
286 dma->ops->enable_dma(cs5535au); 297 dma->ops->enable_dma(cs5535au);
287 break; 298 break;
299 case SNDRV_PCM_TRIGGER_RESUME:
300 dma->ops->enable_dma(cs5535au);
301 dma->suspended = 0;
302 break;
288 case SNDRV_PCM_TRIGGER_STOP: 303 case SNDRV_PCM_TRIGGER_STOP:
289 dma->ops->disable_dma(cs5535au); 304 dma->ops->disable_dma(cs5535au);
290 break; 305 break;
306 case SNDRV_PCM_TRIGGER_SUSPEND:
307 dma->ops->disable_dma(cs5535au);
308 dma->suspended = 1;
309 break;
291 default: 310 default:
292 snd_printk(KERN_ERR "unhandled trigger\n"); 311 snd_printk(KERN_ERR "unhandled trigger\n");
293 err = -EINVAL; 312 err = -EINVAL;
@@ -375,6 +394,7 @@ static struct cs5535audio_dma_ops snd_cs5535audio_playback_dma_ops = {
375 .enable_dma = cs5535audio_playback_enable_dma, 394 .enable_dma = cs5535audio_playback_enable_dma,
376 .disable_dma = cs5535audio_playback_disable_dma, 395 .disable_dma = cs5535audio_playback_disable_dma,
377 .setup_prd = cs5535audio_playback_setup_prd, 396 .setup_prd = cs5535audio_playback_setup_prd,
397 .read_prd = cs5535audio_playback_read_prd,
378 .pause_dma = cs5535audio_playback_pause_dma, 398 .pause_dma = cs5535audio_playback_pause_dma,
379 .read_dma_pntr = cs5535audio_playback_read_dma_pntr, 399 .read_dma_pntr = cs5535audio_playback_read_dma_pntr,
380}; 400};
@@ -384,6 +404,7 @@ static struct cs5535audio_dma_ops snd_cs5535audio_capture_dma_ops = {
384 .enable_dma = cs5535audio_capture_enable_dma, 404 .enable_dma = cs5535audio_capture_enable_dma,
385 .disable_dma = cs5535audio_capture_disable_dma, 405 .disable_dma = cs5535audio_capture_disable_dma,
386 .setup_prd = cs5535audio_capture_setup_prd, 406 .setup_prd = cs5535audio_capture_setup_prd,
407 .read_prd = cs5535audio_capture_read_prd,
387 .pause_dma = cs5535audio_capture_pause_dma, 408 .pause_dma = cs5535audio_capture_pause_dma,
388 .read_dma_pntr = cs5535audio_capture_read_dma_pntr, 409 .read_dma_pntr = cs5535audio_capture_read_dma_pntr,
389}; 410};
@@ -413,6 +434,7 @@ int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535au)
413 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 434 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
414 snd_dma_pci_data(cs5535au->pci), 435 snd_dma_pci_data(cs5535au->pci),
415 64*1024, 128*1024); 436 64*1024, 128*1024);
437 cs5535au->pcm = pcm;
416 438
417 return 0; 439 return 0;
418} 440}
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
new file mode 100644
index 000000000000..aad0e69db9c1
--- /dev/null
+++ b/sound/pci/cs5535audio/cs5535audio_pm.c
@@ -0,0 +1,123 @@
1/*
2 * Power management for audio on multifunction CS5535 companion device
3 * Copyright (C) Jaya Kumar
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <linux/init.h>
22#include <linux/slab.h>
23#include <linux/pci.h>
24#include <linux/delay.h>
25#include <sound/driver.h>
26#include <sound/core.h>
27#include <sound/control.h>
28#include <sound/initval.h>
29#include <sound/asoundef.h>
30#include <sound/pcm.h>
31#include <sound/ac97_codec.h>
32#include "cs5535audio.h"
33
34static void snd_cs5535audio_stop_hardware(struct cs5535audio *cs5535au)
35{
36 /*
37 we depend on snd_ac97_suspend to tell the
38 AC97 codec to shutdown. the amd spec suggests
39 that the LNK_SHUTDOWN be done at the same time
40 that the codec power-down is issued. instead,
41 we do it just after rather than at the same
42 time. excluding codec specific build_ops->suspend
43 ac97 powerdown hits:
44 0x8000 EAPD
45 0x4000 Headphone amplifier
46 0x0300 ADC & DAC
47 0x0400 Analog Mixer powerdown (Vref on)
48 I am not sure if this is the best that we can do.
49 The remainder to be investigated are:
50 - analog mixer (vref off) 0x0800
51 - AC-link powerdown 0x1000
52 - codec internal clock 0x2000
53 */
54
55 /* set LNK_SHUTDOWN to shutdown AC link */
56 cs_writel(cs5535au, ACC_CODEC_CNTL, ACC_CODEC_CNTL_LNK_SHUTDOWN);
57
58}
59
60int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state)
61{
62 struct snd_card *card = pci_get_drvdata(pci);
63 struct cs5535audio *cs5535au = card->private_data;
64 int i;
65
66 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
67 for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
68 struct cs5535audio_dma *dma = &cs5535au->dmas[i];
69 if (dma && dma->substream && !dma->suspended)
70 dma->saved_prd = dma->ops->read_prd(cs5535au);
71 }
72 snd_pcm_suspend_all(cs5535au->pcm);
73 snd_ac97_suspend(cs5535au->ac97);
74 /* save important regs, then disable aclink in hw */
75 snd_cs5535audio_stop_hardware(cs5535au);
76 pci_disable_device(pci);
77 pci_save_state(pci);
78
79 return 0;
80}
81
82int snd_cs5535audio_resume(struct pci_dev *pci)
83{
84 struct snd_card *card = pci_get_drvdata(pci);
85 struct cs5535audio *cs5535au = card->private_data;
86 u32 tmp;
87 int timeout;
88 int i;
89
90 pci_restore_state(pci);
91 pci_enable_device(pci);
92 pci_set_master(pci);
93
94 /* set LNK_WRM_RST to reset AC link */
95 cs_writel(cs5535au, ACC_CODEC_CNTL, ACC_CODEC_CNTL_LNK_WRM_RST);
96
97 timeout = 50;
98 do {
99 tmp = cs_readl(cs5535au, ACC_CODEC_STATUS);
100 if (tmp & PRM_RDY_STS)
101 break;
102 udelay(1);
103 } while (--timeout);
104
105 if (!timeout)
106 snd_printk(KERN_ERR "Failure getting AC Link ready\n");
107
108 /* we depend on ac97 to perform the codec power up */
109 snd_ac97_resume(cs5535au->ac97);
110 /* set up rate regs, dma. actual initiation is done in trig */
111 for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
112 struct cs5535audio_dma *dma = &cs5535au->dmas[i];
113 if (dma && dma->substream && dma->suspended) {
114 dma->substream->ops->prepare(dma->substream);
115 dma->ops->setup_prd(cs5535au, dma->saved_prd);
116 }
117 }
118
119 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
120
121 return 0;
122}
123
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 42b11ba1d210..549673ea14a9 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -46,13 +46,13 @@ MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB Live!/PCI512/E-mu APS},"
46static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 46static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
47static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 47static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
48static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 48static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
49static int extin[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 49static int extin[SNDRV_CARDS];
50static int extout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 50static int extout[SNDRV_CARDS];
51static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4}; 51static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4};
52static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64}; 52static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64};
53static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128}; 53static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
54static int enable_ir[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 54static int enable_ir[SNDRV_CARDS];
55static uint subsystem[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* Force card subsystem model */ 55static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
56 56
57module_param_array(index, int, NULL, 0444); 57module_param_array(index, int, NULL, 0444);
58MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard."); 58MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard.");
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 6bfa08436efa..42a358f989c3 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -777,14 +777,6 @@ static int snd_emu10k1_dev_free(struct snd_device *device)
777 777
778static struct snd_emu_chip_details emu_chip_details[] = { 778static struct snd_emu_chip_details emu_chip_details[] = {
779 /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/ 779 /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/
780 /* Audigy4 SB0400 */
781 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102,
782 .driver = "Audigy2", .name = "Audigy 4 [SB0400]",
783 .id = "Audigy2",
784 .emu10k2_chip = 1,
785 .ca0108_chip = 1,
786 .spk71 = 1,
787 .ac97_chip = 1} ,
788 /* Tested by James@superbug.co.uk 3rd July 2005 */ 780 /* Tested by James@superbug.co.uk 3rd July 2005 */
789 /* DSP: CA0108-IAT 781 /* DSP: CA0108-IAT
790 * DAC: CS4382-KQ 782 * DAC: CS4382-KQ
@@ -799,13 +791,59 @@ static struct snd_emu_chip_details emu_chip_details[] = {
799 .ca0108_chip = 1, 791 .ca0108_chip = 1,
800 .spk71 = 1, 792 .spk71 = 1,
801 .ac97_chip = 1} , 793 .ac97_chip = 1} ,
794 /* Audigy4 (Not PRO) SB0610 */
795 /* Tested by James@superbug.co.uk 4th April 2006 */
796 /* A_IOCFG bits
797 * Output
798 * 0: ?
799 * 1: ?
800 * 2: ?
801 * 3: 0 - Digital Out, 1 - Line in
802 * 4: ?
803 * 5: ?
804 * 6: ?
805 * 7: ?
806 * Input
807 * 8: ?
808 * 9: ?
809 * A: Green jack sense (Front)
810 * B: ?
811 * C: Black jack sense (Rear/Side Right)
812 * D: Yellow jack sense (Center/LFE/Side Left)
813 * E: ?
814 * F: ?
815 *
816 * Digital Out/Line in switch using A_IOCFG bit 3 (0x08)
817 * 0 - Digital Out
818 * 1 - Line in
819 */
820 /* Mic input not tested.
821 * Analog CD input not tested
822 * Digital Out not tested.
823 * Line in working.
824 * Audio output 5.1 working. Side outputs not working.
825 */
826 /* DSP: CA10300-IAT LF
827 * DAC: Cirrus Logic CS4382-KQZ
828 * ADC: Philips 1361T
829 * AC97: Sigmatel STAC9750
830 * CA0151: None
831 */
832 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102,
833 .driver = "Audigy2", .name = "Audigy 4 [SB0610]",
834 .id = "Audigy2",
835 .emu10k2_chip = 1,
836 .ca0108_chip = 1,
837 .spk71 = 1,
838 .adc_1361t = 1, /* 24 bit capture instead of 16bit */
839 .ac97_chip = 1} ,
802 /* Audigy 2 ZS Notebook Cardbus card.*/ 840 /* Audigy 2 ZS Notebook Cardbus card.*/
803 /* Tested by James@superbug.co.uk 22th December 2005 */ 841 /* Tested by James@superbug.co.uk 22th December 2005 */
804 /* Audio output 7.1/Headphones working. 842 /* Audio output 7.1/Headphones working.
805 * Digital output working. (AC3 not checked, only PCM) 843 * Digital output working. (AC3 not checked, only PCM)
806 * Audio inputs not tested. 844 * Audio inputs not tested.
807 */ 845 */
808 /* DSP: Tiny2 846 /* DSP: Tina2
809 * DAC: Wolfson WM8768/WM8568 847 * DAC: Wolfson WM8768/WM8568
810 * ADC: Wolfson WM8775 848 * ADC: Wolfson WM8775
811 * AC97: None 849 * AC97: None
@@ -1421,16 +1459,3 @@ void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
1421 } 1459 }
1422} 1460}
1423#endif 1461#endif
1424
1425/* memory.c */
1426EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
1427EXPORT_SYMBOL(snd_emu10k1_synth_free);
1428EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
1429EXPORT_SYMBOL(snd_emu10k1_synth_copy_from_user);
1430EXPORT_SYMBOL(snd_emu10k1_memblk_map);
1431/* voice.c */
1432EXPORT_SYMBOL(snd_emu10k1_voice_alloc);
1433EXPORT_SYMBOL(snd_emu10k1_voice_free);
1434/* io.c */
1435EXPORT_SYMBOL(snd_emu10k1_ptr_read);
1436EXPORT_SYMBOL(snd_emu10k1_ptr_write);
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index d51290c18167..0fb27e4be07b 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -1055,8 +1055,7 @@ static int __devinit snd_emu10k1x_proc_init(struct emu10k1x * emu)
1055 struct snd_info_entry *entry; 1055 struct snd_info_entry *entry;
1056 1056
1057 if(! snd_card_proc_new(emu->card, "emu10k1x_regs", &entry)) { 1057 if(! snd_card_proc_new(emu->card, "emu10k1x_regs", &entry)) {
1058 snd_info_set_text_ops(entry, emu, 1024, snd_emu10k1x_proc_reg_read); 1058 snd_info_set_text_ops(entry, emu, snd_emu10k1x_proc_reg_read);
1059 entry->c.text.write_size = 64;
1060 entry->c.text.write = snd_emu10k1x_proc_reg_write; 1059 entry->c.text.write = snd_emu10k1x_proc_reg_write;
1061 entry->mode |= S_IWUSR; 1060 entry->mode |= S_IWUSR;
1062 entry->private_data = emu; 1061 entry->private_data = emu;
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 2a9d12d10680..c31f3d0877fa 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -777,6 +777,8 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
777 }; 777 };
778 static char *audigy_remove_ctls[] = { 778 static char *audigy_remove_ctls[] = {
779 /* Master/PCM controls on ac97 of Audigy has no effect */ 779 /* Master/PCM controls on ac97 of Audigy has no effect */
780 /* On the Audigy2 the AC97 playback is piped into
781 * the Philips ADC for 24bit capture */
780 "PCM Playback Switch", 782 "PCM Playback Switch",
781 "PCM Playback Volume", 783 "PCM Playback Volume",
782 "Master Mono Playback Switch", 784 "Master Mono Playback Switch",
@@ -804,6 +806,47 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
804 "AMic Playback Volume", "Mic Playback Volume", 806 "AMic Playback Volume", "Mic Playback Volume",
805 NULL 807 NULL
806 }; 808 };
809 static char *audigy_remove_ctls_1361t_adc[] = {
810 /* On the Audigy2 the AC97 playback is piped into
811 * the Philips ADC for 24bit capture */
812 "PCM Playback Switch",
813 "PCM Playback Volume",
814 "Master Mono Playback Switch",
815 "Master Mono Playback Volume",
816 "Capture Source",
817 "Capture Switch",
818 "Capture Volume",
819 "Mic Capture Volume",
820 "Headphone Playback Switch",
821 "Headphone Playback Volume",
822 "3D Control - Center",
823 "3D Control - Depth",
824 "3D Control - Switch",
825 "Line2 Playback Volume",
826 "Line2 Capture Volume",
827 NULL
828 };
829 static char *audigy_rename_ctls_1361t_adc[] = {
830 "Master Playback Switch", "Master Capture Switch",
831 "Master Playback Volume", "Master Capture Volume",
832 "Wave Master Playback Volume", "Master Playback Volume",
833 "PC Speaker Playback Switch", "PC Speaker Capture Switch",
834 "PC Speaker Playback Volume", "PC Speaker Capture Volume",
835 "Phone Playback Switch", "Phone Capture Switch",
836 "Phone Playback Volume", "Phone Capture Volume",
837 "Mic Playback Switch", "Mic Capture Switch",
838 "Mic Playback Volume", "Mic Capture Volume",
839 "Line Playback Switch", "Line Capture Switch",
840 "Line Playback Volume", "Line Capture Volume",
841 "CD Playback Switch", "CD Capture Switch",
842 "CD Playback Volume", "CD Capture Volume",
843 "Aux Playback Switch", "Aux Capture Switch",
844 "Aux Playback Volume", "Aux Capture Volume",
845 "Video Playback Switch", "Video Capture Switch",
846 "Video Playback Volume", "Video Capture Volume",
847
848 NULL
849 };
807 850
808 if (emu->card_capabilities->ac97_chip) { 851 if (emu->card_capabilities->ac97_chip) {
809 struct snd_ac97_bus *pbus; 852 struct snd_ac97_bus *pbus;
@@ -834,7 +877,10 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
834 snd_ac97_write_cache(emu->ac97, AC97_MASTER, 0x0000); 877 snd_ac97_write_cache(emu->ac97, AC97_MASTER, 0x0000);
835 /* set capture source to mic */ 878 /* set capture source to mic */
836 snd_ac97_write_cache(emu->ac97, AC97_REC_SEL, 0x0000); 879 snd_ac97_write_cache(emu->ac97, AC97_REC_SEL, 0x0000);
837 c = audigy_remove_ctls; 880 if (emu->card_capabilities->adc_1361t)
881 c = audigy_remove_ctls_1361t_adc;
882 else
883 c = audigy_remove_ctls;
838 } else { 884 } else {
839 /* 885 /*
840 * Credits for cards based on STAC9758: 886 * Credits for cards based on STAC9758:
@@ -863,11 +909,15 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
863 } 909 }
864 910
865 if (emu->audigy) 911 if (emu->audigy)
866 c = audigy_rename_ctls; 912 if (emu->card_capabilities->adc_1361t)
913 c = audigy_rename_ctls_1361t_adc;
914 else
915 c = audigy_rename_ctls;
867 else 916 else
868 c = emu10k1_rename_ctls; 917 c = emu10k1_rename_ctls;
869 for (; *c; c += 2) 918 for (; *c; c += 2)
870 rename_ctl(card, c[0], c[1]); 919 rename_ctl(card, c[0], c[1]);
920
871 if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */ 921 if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */
872 rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume"); 922 rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume");
873 rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume"); 923 rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume");
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index 90f1c52703a1..b939e03aaedf 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -532,57 +532,51 @@ int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu)
532 struct snd_info_entry *entry; 532 struct snd_info_entry *entry;
533#ifdef CONFIG_SND_DEBUG 533#ifdef CONFIG_SND_DEBUG
534 if (! snd_card_proc_new(emu->card, "io_regs", &entry)) { 534 if (! snd_card_proc_new(emu->card, "io_regs", &entry)) {
535 snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_io_reg_read); 535 snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read);
536 entry->c.text.write_size = 64;
537 entry->c.text.write = snd_emu_proc_io_reg_write; 536 entry->c.text.write = snd_emu_proc_io_reg_write;
538 entry->mode |= S_IWUSR; 537 entry->mode |= S_IWUSR;
539 } 538 }
540 if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) { 539 if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) {
541 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00a); 540 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read00a);
542 entry->c.text.write_size = 64;
543 entry->c.text.write = snd_emu_proc_ptr_reg_write00; 541 entry->c.text.write = snd_emu_proc_ptr_reg_write00;
544 entry->mode |= S_IWUSR; 542 entry->mode |= S_IWUSR;
545 } 543 }
546 if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) { 544 if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) {
547 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00b); 545 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read00b);
548 entry->c.text.write_size = 64;
549 entry->c.text.write = snd_emu_proc_ptr_reg_write00; 546 entry->c.text.write = snd_emu_proc_ptr_reg_write00;
550 entry->mode |= S_IWUSR; 547 entry->mode |= S_IWUSR;
551 } 548 }
552 if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) { 549 if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) {
553 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20a); 550 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20a);
554 entry->c.text.write_size = 64;
555 entry->c.text.write = snd_emu_proc_ptr_reg_write20; 551 entry->c.text.write = snd_emu_proc_ptr_reg_write20;
556 entry->mode |= S_IWUSR; 552 entry->mode |= S_IWUSR;
557 } 553 }
558 if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) { 554 if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) {
559 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20b); 555 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20b);
560 entry->c.text.write_size = 64;
561 entry->c.text.write = snd_emu_proc_ptr_reg_write20; 556 entry->c.text.write = snd_emu_proc_ptr_reg_write20;
562 entry->mode |= S_IWUSR; 557 entry->mode |= S_IWUSR;
563 } 558 }
564 if (! snd_card_proc_new(emu->card, "ptr_regs20c", &entry)) { 559 if (! snd_card_proc_new(emu->card, "ptr_regs20c", &entry)) {
565 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20c); 560 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20c);
566 entry->c.text.write_size = 64;
567 entry->c.text.write = snd_emu_proc_ptr_reg_write20; 561 entry->c.text.write = snd_emu_proc_ptr_reg_write20;
568 entry->mode |= S_IWUSR; 562 entry->mode |= S_IWUSR;
569 } 563 }
570#endif 564#endif
571 565
572 if (! snd_card_proc_new(emu->card, "emu10k1", &entry)) 566 if (! snd_card_proc_new(emu->card, "emu10k1", &entry))
573 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_read); 567 snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_read);
574 568
575 if (emu->card_capabilities->emu10k2_chip) { 569 if (emu->card_capabilities->emu10k2_chip) {
576 if (! snd_card_proc_new(emu->card, "spdif-in", &entry)) 570 if (! snd_card_proc_new(emu->card, "spdif-in", &entry))
577 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_spdif_read); 571 snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_spdif_read);
578 } 572 }
579 if (emu->card_capabilities->ca0151_chip) { 573 if (emu->card_capabilities->ca0151_chip) {
580 if (! snd_card_proc_new(emu->card, "capture-rates", &entry)) 574 if (! snd_card_proc_new(emu->card, "capture-rates", &entry))
581 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_rates_read); 575 snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_rates_read);
582 } 576 }
583 577
584 if (! snd_card_proc_new(emu->card, "voices", &entry)) 578 if (! snd_card_proc_new(emu->card, "voices", &entry))
585 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_voices_read); 579 snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_voices_read);
586 580
587 if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) { 581 if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) {
588 entry->content = SNDRV_INFO_CONTENT_DATA; 582 entry->content = SNDRV_INFO_CONTENT_DATA;
@@ -616,7 +610,6 @@ int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu)
616 entry->content = SNDRV_INFO_CONTENT_TEXT; 610 entry->content = SNDRV_INFO_CONTENT_TEXT;
617 entry->private_data = emu; 611 entry->private_data = emu;
618 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; 612 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
619 entry->c.text.read_size = 128*1024;
620 entry->c.text.read = snd_emu10k1_proc_acode_read; 613 entry->c.text.read = snd_emu10k1_proc_acode_read;
621 } 614 }
622 return 0; 615 return 0;
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index ef5304df8c11..029e7856c43b 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -62,6 +62,8 @@ unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, un
62 } 62 }
63} 63}
64 64
65EXPORT_SYMBOL(snd_emu10k1_ptr_read);
66
65void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data) 67void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data)
66{ 68{
67 unsigned int regptr; 69 unsigned int regptr;
@@ -92,6 +94,8 @@ void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned i
92 } 94 }
93} 95}
94 96
97EXPORT_SYMBOL(snd_emu10k1_ptr_write);
98
95unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, 99unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu,
96 unsigned int reg, 100 unsigned int reg,
97 unsigned int chn) 101 unsigned int chn)
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index e7ec98649f04..4fcaefe5a3c5 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -287,6 +287,8 @@ int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *b
287 return err; 287 return err;
288} 288}
289 289
290EXPORT_SYMBOL(snd_emu10k1_memblk_map);
291
290/* 292/*
291 * page allocation for DMA 293 * page allocation for DMA
292 */ 294 */
@@ -387,6 +389,7 @@ snd_emu10k1_synth_alloc(struct snd_emu10k1 *hw, unsigned int size)
387 return (struct snd_util_memblk *)blk; 389 return (struct snd_util_memblk *)blk;
388} 390}
389 391
392EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
390 393
391/* 394/*
392 * free a synth sample area 395 * free a synth sample area
@@ -409,6 +412,7 @@ snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *memblk)
409 return 0; 412 return 0;
410} 413}
411 414
415EXPORT_SYMBOL(snd_emu10k1_synth_free);
412 416
413/* check new allocation range */ 417/* check new allocation range */
414static void get_single_page_range(struct snd_util_memhdr *hdr, 418static void get_single_page_range(struct snd_util_memhdr *hdr,
@@ -540,6 +544,8 @@ int snd_emu10k1_synth_bzero(struct snd_emu10k1 *emu, struct snd_util_memblk *blk
540 return 0; 544 return 0;
541} 545}
542 546
547EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
548
543/* 549/*
544 * copy_from_user(blk + offset, data, size) 550 * copy_from_user(blk + offset, data, size)
545 */ 551 */
@@ -568,3 +574,5 @@ int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_me
568 } while (offset < end_offset); 574 } while (offset < end_offset);
569 return 0; 575 return 0;
570} 576}
577
578EXPORT_SYMBOL(snd_emu10k1_synth_copy_from_user);
diff --git a/sound/pci/emu10k1/p17v.h b/sound/pci/emu10k1/p17v.h
new file mode 100644
index 000000000000..7ddb5be632cf
--- /dev/null
+++ b/sound/pci/emu10k1/p17v.h
@@ -0,0 +1,111 @@
1/*
2 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver p17v chips
4 * Version: 0.01
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22/******************************************************************************/
23/* Audigy2Value Tina (P17V) pointer-offset register set,
24 * accessed through the PTR20 and DATA24 registers */
25/******************************************************************************/
26
27/* 00 - 07: Not used */
28#define P17V_PLAYBACK_FIFO_PTR 0x08 /* Current playback fifo pointer
29 * and number of sound samples in cache.
30 */
31/* 09 - 12: Not used */
32#define P17V_CAPTURE_FIFO_PTR 0x13 /* Current capture fifo pointer
33 * and number of sound samples in cache.
34 */
35/* 14 - 17: Not used */
36#define P17V_PB_CHN_SEL 0x18 /* P17v playback channel select */
37#define P17V_SE_SLOT_SEL_L 0x19 /* Sound Engine slot select low */
38#define P17V_SE_SLOT_SEL_H 0x1a /* Sound Engine slot select high */
39/* 1b - 1f: Not used */
40/* 20 - 2f: Not used */
41/* 30 - 3b: Not used */
42#define P17V_SPI 0x3c /* SPI interface register */
43#define P17V_I2C_ADDR 0x3d /* I2C Address */
44#define P17V_I2C_0 0x3e /* I2C Data */
45#define P17V_I2C_1 0x3f /* I2C Data */
46
47#define P17V_START_AUDIO 0x40 /* Start Audio bit */
48/* 41 - 47: Reserved */
49#define P17V_START_CAPTURE 0x48 /* Start Capture bit */
50#define P17V_CAPTURE_FIFO_BASE 0x49 /* Record FIFO base address */
51#define P17V_CAPTURE_FIFO_SIZE 0x4a /* Record FIFO buffer size */
52#define P17V_CAPTURE_FIFO_INDEX 0x4b /* Record FIFO capture index */
53#define P17V_CAPTURE_VOL_H 0x4c /* P17v capture volume control */
54#define P17V_CAPTURE_VOL_L 0x4d /* P17v capture volume control */
55/* 4e - 4f: Not used */
56/* 50 - 5f: Not used */
57#define P17V_SRCSel 0x60 /* SRC48 and SRCMulti sample rate select
58 * and output select
59 */
60#define P17V_MIXER_AC97_10K1_VOL_L 0x61 /* 10K to Mixer_AC97 input volume control */
61#define P17V_MIXER_AC97_10K1_VOL_H 0x62 /* 10K to Mixer_AC97 input volume control */
62#define P17V_MIXER_AC97_P17V_VOL_L 0x63 /* P17V to Mixer_AC97 input volume control */
63#define P17V_MIXER_AC97_P17V_VOL_H 0x64 /* P17V to Mixer_AC97 input volume control */
64#define P17V_MIXER_AC97_SRP_REC_VOL_L 0x65 /* SRP Record to Mixer_AC97 input volume control */
65#define P17V_MIXER_AC97_SRP_REC_VOL_H 0x66 /* SRP Record to Mixer_AC97 input volume control */
66/* 67 - 68: Reserved */
67#define P17V_MIXER_Spdif_10K1_VOL_L 0x69 /* 10K to Mixer_Spdif input volume control */
68#define P17V_MIXER_Spdif_10K1_VOL_H 0x6A /* 10K to Mixer_Spdif input volume control */
69#define P17V_MIXER_Spdif_P17V_VOL_L 0x6B /* P17V to Mixer_Spdif input volume control */
70#define P17V_MIXER_Spdif_P17V_VOL_H 0x6C /* P17V to Mixer_Spdif input volume control */
71#define P17V_MIXER_Spdif_SRP_REC_VOL_L 0x6D /* SRP Record to Mixer_Spdif input volume control */
72#define P17V_MIXER_Spdif_SRP_REC_VOL_H 0x6E /* SRP Record to Mixer_Spdif input volume control */
73/* 6f - 70: Reserved */
74#define P17V_MIXER_I2S_10K1_VOL_L 0x71 /* 10K to Mixer_I2S input volume control */
75#define P17V_MIXER_I2S_10K1_VOL_H 0x72 /* 10K to Mixer_I2S input volume control */
76#define P17V_MIXER_I2S_P17V_VOL_L 0x73 /* P17V to Mixer_I2S input volume control */
77#define P17V_MIXER_I2S_P17V_VOL_H 0x74 /* P17V to Mixer_I2S input volume control */
78#define P17V_MIXER_I2S_SRP_REC_VOL_L 0x75 /* SRP Record to Mixer_I2S input volume control */
79#define P17V_MIXER_I2S_SRP_REC_VOL_H 0x76 /* SRP Record to Mixer_I2S input volume control */
80/* 77 - 78: Reserved */
81#define P17V_MIXER_AC97_ENABLE 0x79 /* Mixer AC97 input audio enable */
82#define P17V_MIXER_SPDIF_ENABLE 0x7A /* Mixer SPDIF input audio enable */
83#define P17V_MIXER_I2S_ENABLE 0x7B /* Mixer I2S input audio enable */
84#define P17V_AUDIO_OUT_ENABLE 0x7C /* Audio out enable */
85#define P17V_MIXER_ATT 0x7D /* SRP Mixer Attenuation Select */
86#define P17V_SRP_RECORD_SRR 0x7E /* SRP Record channel source Select */
87#define P17V_SOFT_RESET_SRP_MIXER 0x7F /* SRP and mixer soft reset */
88
89#define P17V_AC97_OUT_MASTER_VOL_L 0x80 /* AC97 Output master volume control */
90#define P17V_AC97_OUT_MASTER_VOL_H 0x81 /* AC97 Output master volume control */
91#define P17V_SPDIF_OUT_MASTER_VOL_L 0x82 /* SPDIF Output master volume control */
92#define P17V_SPDIF_OUT_MASTER_VOL_H 0x83 /* SPDIF Output master volume control */
93#define P17V_I2S_OUT_MASTER_VOL_L 0x84 /* I2S Output master volume control */
94#define P17V_I2S_OUT_MASTER_VOL_H 0x85 /* I2S Output master volume control */
95/* 86 - 87: Not used */
96#define P17V_I2S_CHANNEL_SWAP_PHASE_INVERSE 0x88 /* I2S out mono channel swap
97 * and phase inverse */
98#define P17V_SPDIF_CHANNEL_SWAP_PHASE_INVERSE 0x89 /* SPDIF out mono channel swap
99 * and phase inverse */
100/* 8A: Not used */
101#define P17V_SRP_P17V_ESR 0x8B /* SRP_P17V estimated sample rate and rate lock */
102#define P17V_SRP_REC_ESR 0x8C /* SRP_REC estimated sample rate and rate lock */
103#define P17V_SRP_BYPASS 0x8D /* srps channel bypass and srps bypass */
104/* 8E - 92: Not used */
105#define P17V_I2S_SRC_SEL 0x93 /* I2SIN mode sel */
106
107
108
109
110
111
diff --git a/sound/pci/emu10k1/tina2.h b/sound/pci/emu10k1/tina2.h
index 5c43abf03e89..f2d8eb6c89e1 100644
--- a/sound/pci/emu10k1/tina2.h
+++ b/sound/pci/emu10k1/tina2.h
@@ -1,11 +1,7 @@
1/* 1/*
2 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk> 2 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver p16v chips 3 * Driver tina2 chips
4 * Version: 0.21 4 * Version: 0.1
5 *
6 *
7 * This code was initally based on code from ALSA's emu10k1x.c which is:
8 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
9 * 5 *
10 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c
index 56ffb7dc3ee2..94eca82dd4fc 100644
--- a/sound/pci/emu10k1/voice.c
+++ b/sound/pci/emu10k1/voice.c
@@ -139,6 +139,8 @@ int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int number,
139 return result; 139 return result;
140} 140}
141 141
142EXPORT_SYMBOL(snd_emu10k1_voice_alloc);
143
142int snd_emu10k1_voice_free(struct snd_emu10k1 *emu, 144int snd_emu10k1_voice_free(struct snd_emu10k1 *emu,
143 struct snd_emu10k1_voice *pvoice) 145 struct snd_emu10k1_voice *pvoice)
144{ 146{
@@ -153,3 +155,5 @@ int snd_emu10k1_voice_free(struct snd_emu10k1 *emu,
153 spin_unlock_irqrestore(&emu->voice_lock, flags); 155 spin_unlock_irqrestore(&emu->voice_lock, flags);
154 return 0; 156 return 0;
155} 157}
158
159EXPORT_SYMBOL(snd_emu10k1_voice_free);
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index ca9e34e88f62..9d46bbee2a40 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -1915,7 +1915,7 @@ static void __devinit snd_ensoniq_proc_init(struct ensoniq * ensoniq)
1915 struct snd_info_entry *entry; 1915 struct snd_info_entry *entry;
1916 1916
1917 if (! snd_card_proc_new(ensoniq->card, "audiopci", &entry)) 1917 if (! snd_card_proc_new(ensoniq->card, "audiopci", &entry))
1918 snd_info_set_text_ops(entry, ensoniq, 1024, snd_ensoniq_proc_read); 1918 snd_info_set_text_ops(entry, ensoniq, snd_ensoniq_proc_read);
1919} 1919}
1920 1920
1921/* 1921/*
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 6f9094ca4fb4..ca6603fe0b11 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1756,7 +1756,8 @@ static int __devinit snd_es1938_probe(struct pci_dev *pci,
1756 } 1756 }
1757 } 1757 }
1758 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 1758 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
1759 chip->mpu_port, 1, chip->irq, 0, &chip->rmidi) < 0) { 1759 chip->mpu_port, MPU401_INFO_INTEGRATED,
1760 chip->irq, 0, &chip->rmidi) < 0) {
1760 printk(KERN_ERR "es1938: unable to initialize MPU-401\n"); 1761 printk(KERN_ERR "es1938: unable to initialize MPU-401\n");
1761 } else { 1762 } else {
1762 // this line is vital for MIDI interrupt handling on ess-solo1 1763 // this line is vital for MIDI interrupt handling on ess-solo1
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 5ff4175c7b6d..bfa0876e715e 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -132,7 +132,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
132static int total_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1024 }; 132static int total_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1024 };
133static int pcm_substreams_p[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4 }; 133static int pcm_substreams_p[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4 };
134static int pcm_substreams_c[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1 }; 134static int pcm_substreams_c[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1 };
135static int clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 135static int clock[SNDRV_CARDS];
136static int use_pm[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; 136static int use_pm[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
137static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; 137static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
138#ifdef SUPPORT_JOYSTICK 138#ifdef SUPPORT_JOYSTICK
@@ -2727,7 +2727,8 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci,
2727 } 2727 }
2728 if (enable_mpu[dev]) { 2728 if (enable_mpu[dev]) {
2729 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 2729 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
2730 chip->io_port + ESM_MPU401_PORT, 1, 2730 chip->io_port + ESM_MPU401_PORT,
2731 MPU401_INFO_INTEGRATED,
2731 chip->irq, 0, &chip->rmidi)) < 0) { 2732 chip->irq, 0, &chip->rmidi)) < 0) {
2732 printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n"); 2733 printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n");
2733 } 2734 }
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index d72fc28c580e..0afa573dd244 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -56,7 +56,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
56 * 3 = MediaForte 64-PCR 56 * 3 = MediaForte 64-PCR
57 * High 16-bits are video (radio) device number + 1 57 * High 16-bits are video (radio) device number + 1
58 */ 58 */
59static int tea575x_tuner[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; 59static int tea575x_tuner[SNDRV_CARDS];
60 60
61module_param_array(index, int, NULL, 0444); 61module_param_array(index, int, NULL, 0444);
62MODULE_PARM_DESC(index, "Index value for the FM801 soundcard."); 62MODULE_PARM_DESC(index, "Index value for the FM801 soundcard.");
@@ -1448,7 +1448,8 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
1448 return err; 1448 return err;
1449 } 1449 }
1450 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801, 1450 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801,
1451 FM801_REG(chip, MPU401_DATA), 1, 1451 FM801_REG(chip, MPU401_DATA),
1452 MPU401_INFO_INTEGRATED,
1452 chip->irq, 0, &chip->rmidi)) < 0) { 1453 chip->irq, 0, &chip->rmidi)) < 0) {
1453 snd_card_free(card); 1454 snd_card_free(card);
1454 return err; 1455 return err;
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index ddfb5ff7fb8f..dbacba6177db 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,5 +1,5 @@
1snd-hda-intel-objs := hda_intel.o 1snd-hda-intel-objs := hda_intel.o
2snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o patch_si3054.o 2snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o patch_si3054.o patch_atihdmi.o
3ifdef CONFIG_PROC_FS 3ifdef CONFIG_PROC_FS
4snd-hda-codec-objs += hda_proc.o 4snd-hda-codec-objs += hda_proc.o
5endif 5endif
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 5bee3b536478..8c2a8174ece1 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -86,6 +86,8 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int dire
86 return res; 86 return res;
87} 87}
88 88
89EXPORT_SYMBOL(snd_hda_codec_read);
90
89/** 91/**
90 * snd_hda_codec_write - send a single command without waiting for response 92 * snd_hda_codec_write - send a single command without waiting for response
91 * @codec: the HDA codec 93 * @codec: the HDA codec
@@ -108,6 +110,8 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
108 return err; 110 return err;
109} 111}
110 112
113EXPORT_SYMBOL(snd_hda_codec_write);
114
111/** 115/**
112 * snd_hda_sequence_write - sequence writes 116 * snd_hda_sequence_write - sequence writes
113 * @codec: the HDA codec 117 * @codec: the HDA codec
@@ -122,6 +126,8 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
122 snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param); 126 snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
123} 127}
124 128
129EXPORT_SYMBOL(snd_hda_sequence_write);
130
125/** 131/**
126 * snd_hda_get_sub_nodes - get the range of sub nodes 132 * snd_hda_get_sub_nodes - get the range of sub nodes
127 * @codec: the HDA codec 133 * @codec: the HDA codec
@@ -140,6 +146,8 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *sta
140 return (int)(parm & 0x7fff); 146 return (int)(parm & 0x7fff);
141} 147}
142 148
149EXPORT_SYMBOL(snd_hda_get_sub_nodes);
150
143/** 151/**
144 * snd_hda_get_connections - get connection list 152 * snd_hda_get_connections - get connection list
145 * @codec: the HDA codec 153 * @codec: the HDA codec
@@ -256,6 +264,8 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
256 return 0; 264 return 0;
257} 265}
258 266
267EXPORT_SYMBOL(snd_hda_queue_unsol_event);
268
259/* 269/*
260 * process queueud unsolicited events 270 * process queueud unsolicited events
261 */ 271 */
@@ -384,6 +394,7 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
384 return 0; 394 return 0;
385} 395}
386 396
397EXPORT_SYMBOL(snd_hda_bus_new);
387 398
388/* 399/*
389 * find a matching codec preset 400 * find a matching codec preset
@@ -587,6 +598,8 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
587 return 0; 598 return 0;
588} 599}
589 600
601EXPORT_SYMBOL(snd_hda_codec_new);
602
590/** 603/**
591 * snd_hda_codec_setup_stream - set up the codec for streaming 604 * snd_hda_codec_setup_stream - set up the codec for streaming
592 * @codec: the CODEC to set up 605 * @codec: the CODEC to set up
@@ -609,6 +622,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stre
609 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format); 622 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format);
610} 623}
611 624
625EXPORT_SYMBOL(snd_hda_codec_setup_stream);
612 626
613/* 627/*
614 * amp access functions 628 * amp access functions
@@ -1294,6 +1308,7 @@ int snd_hda_build_controls(struct hda_bus *bus)
1294 return 0; 1308 return 0;
1295} 1309}
1296 1310
1311EXPORT_SYMBOL(snd_hda_build_controls);
1297 1312
1298/* 1313/*
1299 * stream formats 1314 * stream formats
@@ -1382,6 +1397,8 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
1382 return val; 1397 return val;
1383} 1398}
1384 1399
1400EXPORT_SYMBOL(snd_hda_calc_stream_format);
1401
1385/** 1402/**
1386 * snd_hda_query_supported_pcm - query the supported PCM rates and formats 1403 * snd_hda_query_supported_pcm - query the supported PCM rates and formats
1387 * @codec: the HDA codec 1404 * @codec: the HDA codec
@@ -1663,6 +1680,7 @@ int snd_hda_build_pcms(struct hda_bus *bus)
1663 return 0; 1680 return 0;
1664} 1681}
1665 1682
1683EXPORT_SYMBOL(snd_hda_build_pcms);
1666 1684
1667/** 1685/**
1668 * snd_hda_check_board_config - compare the current codec with the config table 1686 * snd_hda_check_board_config - compare the current codec with the config table
@@ -2165,6 +2183,8 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
2165 return 0; 2183 return 0;
2166} 2184}
2167 2185
2186EXPORT_SYMBOL(snd_hda_suspend);
2187
2168/** 2188/**
2169 * snd_hda_resume - resume the codecs 2189 * snd_hda_resume - resume the codecs
2170 * @bus: the HDA bus 2190 * @bus: the HDA bus
@@ -2187,6 +2207,8 @@ int snd_hda_resume(struct hda_bus *bus)
2187 return 0; 2207 return 0;
2188} 2208}
2189 2209
2210EXPORT_SYMBOL(snd_hda_resume);
2211
2190/** 2212/**
2191 * snd_hda_resume_ctls - resume controls in the new control list 2213 * snd_hda_resume_ctls - resume controls in the new control list
2192 * @codec: the HDA codec 2214 * @codec: the HDA codec
@@ -2247,25 +2269,6 @@ int snd_hda_resume_spdif_in(struct hda_codec *codec)
2247#endif 2269#endif
2248 2270
2249/* 2271/*
2250 * symbols exported for controller modules
2251 */
2252EXPORT_SYMBOL(snd_hda_codec_read);
2253EXPORT_SYMBOL(snd_hda_codec_write);
2254EXPORT_SYMBOL(snd_hda_sequence_write);
2255EXPORT_SYMBOL(snd_hda_get_sub_nodes);
2256EXPORT_SYMBOL(snd_hda_queue_unsol_event);
2257EXPORT_SYMBOL(snd_hda_bus_new);
2258EXPORT_SYMBOL(snd_hda_codec_new);
2259EXPORT_SYMBOL(snd_hda_codec_setup_stream);
2260EXPORT_SYMBOL(snd_hda_calc_stream_format);
2261EXPORT_SYMBOL(snd_hda_build_pcms);
2262EXPORT_SYMBOL(snd_hda_build_controls);
2263#ifdef CONFIG_PM
2264EXPORT_SYMBOL(snd_hda_suspend);
2265EXPORT_SYMBOL(snd_hda_resume);
2266#endif
2267
2268/*
2269 * INIT part 2272 * INIT part
2270 */ 2273 */
2271 2274
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index e821d65afa11..4070b5cd9b6b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -82,6 +82,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
82 "{Intel, ICH8}," 82 "{Intel, ICH8},"
83 "{ATI, SB450}," 83 "{ATI, SB450},"
84 "{ATI, SB600}," 84 "{ATI, SB600},"
85 "{ATI, RS600},"
85 "{VIA, VT8251}," 86 "{VIA, VT8251},"
86 "{VIA, VT8237A}," 87 "{VIA, VT8237A},"
87 "{SiS, SIS966}," 88 "{SiS, SIS966},"
@@ -167,6 +168,12 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
167#define ULI_PLAYBACK_INDEX 5 168#define ULI_PLAYBACK_INDEX 5
168#define ULI_NUM_PLAYBACK 6 169#define ULI_NUM_PLAYBACK 6
169 170
171/* ATI HDMI has 1 playback and 0 capture */
172#define ATIHDMI_CAPTURE_INDEX 0
173#define ATIHDMI_NUM_CAPTURE 0
174#define ATIHDMI_PLAYBACK_INDEX 0
175#define ATIHDMI_NUM_PLAYBACK 1
176
170/* this number is statically defined for simplicity */ 177/* this number is statically defined for simplicity */
171#define MAX_AZX_DEV 16 178#define MAX_AZX_DEV 16
172 179
@@ -331,6 +338,7 @@ struct azx {
331enum { 338enum {
332 AZX_DRIVER_ICH, 339 AZX_DRIVER_ICH,
333 AZX_DRIVER_ATI, 340 AZX_DRIVER_ATI,
341 AZX_DRIVER_ATIHDMI,
334 AZX_DRIVER_VIA, 342 AZX_DRIVER_VIA,
335 AZX_DRIVER_SIS, 343 AZX_DRIVER_SIS,
336 AZX_DRIVER_ULI, 344 AZX_DRIVER_ULI,
@@ -340,6 +348,7 @@ enum {
340static char *driver_short_names[] __devinitdata = { 348static char *driver_short_names[] __devinitdata = {
341 [AZX_DRIVER_ICH] = "HDA Intel", 349 [AZX_DRIVER_ICH] = "HDA Intel",
342 [AZX_DRIVER_ATI] = "HDA ATI SB", 350 [AZX_DRIVER_ATI] = "HDA ATI SB",
351 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
343 [AZX_DRIVER_VIA] = "HDA VIA VT82xx", 352 [AZX_DRIVER_VIA] = "HDA VIA VT82xx",
344 [AZX_DRIVER_SIS] = "HDA SIS966", 353 [AZX_DRIVER_SIS] = "HDA SIS966",
345 [AZX_DRIVER_ULI] = "HDA ULI M5461", 354 [AZX_DRIVER_ULI] = "HDA ULI M5461",
@@ -1393,10 +1402,10 @@ static int azx_free(struct azx *chip)
1393 msleep(1); 1402 msleep(1);
1394 } 1403 }
1395 1404
1396 if (chip->remap_addr)
1397 iounmap(chip->remap_addr);
1398 if (chip->irq >= 0) 1405 if (chip->irq >= 0)
1399 free_irq(chip->irq, (void*)chip); 1406 free_irq(chip->irq, (void*)chip);
1407 if (chip->remap_addr)
1408 iounmap(chip->remap_addr);
1400 1409
1401 if (chip->bdl.area) 1410 if (chip->bdl.area)
1402 snd_dma_free_pages(&chip->bdl); 1411 snd_dma_free_pages(&chip->bdl);
@@ -1495,6 +1504,12 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
1495 chip->playback_index_offset = ULI_PLAYBACK_INDEX; 1504 chip->playback_index_offset = ULI_PLAYBACK_INDEX;
1496 chip->capture_index_offset = ULI_CAPTURE_INDEX; 1505 chip->capture_index_offset = ULI_CAPTURE_INDEX;
1497 break; 1506 break;
1507 case AZX_DRIVER_ATIHDMI:
1508 chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
1509 chip->capture_streams = ATIHDMI_NUM_CAPTURE;
1510 chip->playback_index_offset = ATIHDMI_PLAYBACK_INDEX;
1511 chip->capture_index_offset = ATIHDMI_CAPTURE_INDEX;
1512 break;
1498 default: 1513 default:
1499 chip->playback_streams = ICH6_NUM_PLAYBACK; 1514 chip->playback_streams = ICH6_NUM_PLAYBACK;
1500 chip->capture_streams = ICH6_NUM_CAPTURE; 1515 chip->capture_streams = ICH6_NUM_CAPTURE;
@@ -1621,6 +1636,7 @@ static struct pci_device_id azx_ids[] __devinitdata = {
1621 { 0x8086, 0x284b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH8 */ 1636 { 0x8086, 0x284b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH8 */
1622 { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */ 1637 { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */
1623 { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */ 1638 { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */
1639 { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */
1624 { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ 1640 { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
1625 { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ 1641 { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
1626 { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ 1642 { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h
index acaef3c811b8..0b668793face 100644
--- a/sound/pci/hda/hda_patch.h
+++ b/sound/pci/hda/hda_patch.h
@@ -12,6 +12,8 @@ extern struct hda_codec_preset snd_hda_preset_analog[];
12extern struct hda_codec_preset snd_hda_preset_sigmatel[]; 12extern struct hda_codec_preset snd_hda_preset_sigmatel[];
13/* SiLabs 3054/3055 modem codecs */ 13/* SiLabs 3054/3055 modem codecs */
14extern struct hda_codec_preset snd_hda_preset_si3054[]; 14extern struct hda_codec_preset snd_hda_preset_si3054[];
15/* ATI HDMI codecs */
16extern struct hda_codec_preset snd_hda_preset_atihdmi[];
15 17
16static const struct hda_codec_preset *hda_preset_tables[] = { 18static const struct hda_codec_preset *hda_preset_tables[] = {
17 snd_hda_preset_realtek, 19 snd_hda_preset_realtek,
@@ -19,5 +21,6 @@ static const struct hda_codec_preset *hda_preset_tables[] = {
19 snd_hda_preset_analog, 21 snd_hda_preset_analog,
20 snd_hda_preset_sigmatel, 22 snd_hda_preset_sigmatel,
21 snd_hda_preset_si3054, 23 snd_hda_preset_si3054,
24 snd_hda_preset_atihdmi,
22 NULL 25 NULL
23}; 26};
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index ca514a6a5875..c2f0fe85bf35 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -182,6 +182,10 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
182 snd_iprintf(buffer, " OUT"); 182 snd_iprintf(buffer, " OUT");
183 if (caps & AC_PINCAP_HP_DRV) 183 if (caps & AC_PINCAP_HP_DRV)
184 snd_iprintf(buffer, " HP"); 184 snd_iprintf(buffer, " HP");
185 if (caps & AC_PINCAP_EAPD)
186 snd_iprintf(buffer, " EAPD");
187 if (caps & AC_PINCAP_PRES_DETECT)
188 snd_iprintf(buffer, " Detect");
185 snd_iprintf(buffer, "\n"); 189 snd_iprintf(buffer, "\n");
186 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); 190 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
187 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps, 191 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
@@ -318,7 +322,7 @@ int snd_hda_codec_proc_new(struct hda_codec *codec)
318 if (err < 0) 322 if (err < 0)
319 return err; 323 return err;
320 324
321 snd_info_set_text_ops(entry, codec, 32 * 1024, print_codec_info); 325 snd_info_set_text_ops(entry, codec, print_codec_info);
322 return 0; 326 return 0;
323} 327}
324 328
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 40f000ba1362..dd4e00a82b55 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -789,6 +789,8 @@ static struct hda_board_config ad1986a_cfg_tbl[] = {
789 { .modelname = "3stack", .config = AD1986A_3STACK }, 789 { .modelname = "3stack", .config = AD1986A_3STACK },
790 { .pci_subvendor = 0x10de, .pci_subdevice = 0xcb84, 790 { .pci_subvendor = 0x10de, .pci_subdevice = 0xcb84,
791 .config = AD1986A_3STACK }, /* ASUS A8N-VM CSM */ 791 .config = AD1986A_3STACK }, /* ASUS A8N-VM CSM */
792 { .pci_subvendor = 0x1043, .pci_subdevice = 0x81b3,
793 .config = AD1986A_3STACK }, /* ASUS P5RD2-VM / P5GPL-X SE */
792 { .modelname = "laptop", .config = AD1986A_LAPTOP }, 794 { .modelname = "laptop", .config = AD1986A_LAPTOP },
793 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc01e, 795 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc01e,
794 .config = AD1986A_LAPTOP }, /* FSC V2060 */ 796 .config = AD1986A_LAPTOP }, /* FSC V2060 */
@@ -809,6 +811,8 @@ static struct hda_board_config ad1986a_cfg_tbl[] = {
809 .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */ 811 .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */
810 { .pci_subvendor = 0x103c, .pci_subdevice = 0x30af, 812 { .pci_subvendor = 0x103c, .pci_subdevice = 0x30af,
811 .config = AD1986A_LAPTOP_EAPD }, /* HP Compaq Presario B2800 */ 813 .config = AD1986A_LAPTOP_EAPD }, /* HP Compaq Presario B2800 */
814 { .pci_subvendor = 0x17aa, .pci_subdevice = 0x2066,
815 .config = AD1986A_LAPTOP_EAPD }, /* Lenovo 3000 N100-07684JU */
812 {} 816 {}
813}; 817};
814 818
@@ -963,7 +967,7 @@ static struct snd_kcontrol_new ad1983_mixers[] = {
963 }, 967 },
964 { 968 {
965 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 969 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
966 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", 970 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
967 .info = ad1983_spdif_route_info, 971 .info = ad1983_spdif_route_info,
968 .get = ad1983_spdif_route_get, 972 .get = ad1983_spdif_route_get,
969 .put = ad1983_spdif_route_put, 973 .put = ad1983_spdif_route_put,
@@ -1103,7 +1107,7 @@ static struct snd_kcontrol_new ad1981_mixers[] = {
1103 /* identical with AD1983 */ 1107 /* identical with AD1983 */
1104 { 1108 {
1105 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1109 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1106 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", 1110 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1107 .info = ad1983_spdif_route_info, 1111 .info = ad1983_spdif_route_info,
1108 .get = ad1983_spdif_route_get, 1112 .get = ad1983_spdif_route_get,
1109 .put = ad1983_spdif_route_put, 1113 .put = ad1983_spdif_route_put,
@@ -1329,13 +1333,60 @@ static int ad1981_hp_init(struct hda_codec *codec)
1329 return 0; 1333 return 0;
1330} 1334}
1331 1335
1336/* configuration for Lenovo Thinkpad T60 */
1337static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1338 HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1339 HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1340 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1341 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1342 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1343 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1344 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1345 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1346 HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
1347 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1348 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1349 {
1350 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1351 .name = "Capture Source",
1352 .info = ad198x_mux_enum_info,
1353 .get = ad198x_mux_enum_get,
1354 .put = ad198x_mux_enum_put,
1355 },
1356 /* identical with AD1983 */
1357 {
1358 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1359 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1360 .info = ad1983_spdif_route_info,
1361 .get = ad1983_spdif_route_get,
1362 .put = ad1983_spdif_route_put,
1363 },
1364 { } /* end */
1365};
1366
1367static struct hda_input_mux ad1981_thinkpad_capture_source = {
1368 .num_items = 3,
1369 .items = {
1370 { "Mic", 0x0 },
1371 { "Mix", 0x2 },
1372 { "CD", 0x4 },
1373 },
1374};
1375
1332/* models */ 1376/* models */
1333enum { AD1981_BASIC, AD1981_HP }; 1377enum { AD1981_BASIC, AD1981_HP, AD1981_THINKPAD };
1334 1378
1335static struct hda_board_config ad1981_cfg_tbl[] = { 1379static struct hda_board_config ad1981_cfg_tbl[] = {
1336 { .modelname = "hp", .config = AD1981_HP }, 1380 { .modelname = "hp", .config = AD1981_HP },
1337 /* All HP models */ 1381 /* All HP models */
1338 { .pci_subvendor = 0x103c, .config = AD1981_HP }, 1382 { .pci_subvendor = 0x103c, .config = AD1981_HP },
1383 { .pci_subvendor = 0x30b0, .pci_subdevice = 0x103c,
1384 .config = AD1981_HP }, /* HP nx6320 (reversed SSID, H/W bug) */
1385 { .modelname = "thinkpad", .config = AD1981_THINKPAD },
1386 /* Lenovo Thinkpad T60/X60/Z6xx */
1387 { .pci_subvendor = 0x17aa, .config = AD1981_THINKPAD },
1388 { .pci_subvendor = 0x1014, .pci_subdevice = 0x0597,
1389 .config = AD1981_THINKPAD }, /* Z60m/t */
1339 { .modelname = "basic", .config = AD1981_BASIC }, 1390 { .modelname = "basic", .config = AD1981_BASIC },
1340 {} 1391 {}
1341}; 1392};
@@ -1381,6 +1432,10 @@ static int patch_ad1981(struct hda_codec *codec)
1381 codec->patch_ops.init = ad1981_hp_init; 1432 codec->patch_ops.init = ad1981_hp_init;
1382 codec->patch_ops.unsol_event = ad1981_hp_unsol_event; 1433 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1383 break; 1434 break;
1435 case AD1981_THINKPAD:
1436 spec->mixers[0] = ad1981_thinkpad_mixers;
1437 spec->input_mux = &ad1981_thinkpad_capture_source;
1438 break;
1384 } 1439 }
1385 1440
1386 return 0; 1441 return 0;
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
new file mode 100644
index 000000000000..a27440ffd1c8
--- /dev/null
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -0,0 +1,165 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ATI HDMI codecs
5 *
6 * Copyright (c) 2006 ATI Technologies Inc.
7 *
8 *
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <sound/driver.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/slab.h>
28#include <linux/pci.h>
29#include <sound/core.h>
30#include "hda_codec.h"
31#include "hda_local.h"
32
33struct atihdmi_spec {
34 struct hda_multi_out multiout;
35
36 struct hda_pcm pcm_rec;
37};
38
39static struct hda_verb atihdmi_basic_init[] = {
40 /* enable digital output on pin widget */
41 { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
42 {} /* terminator */
43};
44
45/*
46 * Controls
47 */
48static int atihdmi_build_controls(struct hda_codec *codec)
49{
50 struct atihdmi_spec *spec = codec->spec;
51 int err;
52
53 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
54 if (err < 0)
55 return err;
56
57 return 0;
58}
59
60static int atihdmi_init(struct hda_codec *codec)
61{
62 snd_hda_sequence_write(codec, atihdmi_basic_init);
63 return 0;
64}
65
66#ifdef CONFIG_PM
67/*
68 * resume
69 */
70static int atihdmi_resume(struct hda_codec *codec)
71{
72 atihdmi_init(codec);
73 snd_hda_resume_spdif_out(codec);
74
75 return 0;
76}
77#endif
78
79/*
80 * Digital out
81 */
82static int atihdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
83 struct hda_codec *codec,
84 struct snd_pcm_substream *substream)
85{
86 struct atihdmi_spec *spec = codec->spec;
87 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
88}
89
90static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
91 struct hda_codec *codec,
92 struct snd_pcm_substream *substream)
93{
94 struct atihdmi_spec *spec = codec->spec;
95 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
96}
97
98static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
99 .substreams = 1,
100 .channels_min = 2,
101 .channels_max = 2,
102 .nid = 0x2, /* NID to query formats and rates and setup streams */
103 .ops = {
104 .open = atihdmi_dig_playback_pcm_open,
105 .close = atihdmi_dig_playback_pcm_close
106 },
107};
108
109static int atihdmi_build_pcms(struct hda_codec *codec)
110{
111 struct atihdmi_spec *spec = codec->spec;
112 struct hda_pcm *info = &spec->pcm_rec;
113
114 codec->num_pcms = 1;
115 codec->pcm_info = info;
116
117 info->name = "ATI HDMI";
118 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = atihdmi_pcm_digital_playback;
119
120 return 0;
121}
122
123static void atihdmi_free(struct hda_codec *codec)
124{
125 kfree(codec->spec);
126}
127
128static struct hda_codec_ops atihdmi_patch_ops = {
129 .build_controls = atihdmi_build_controls,
130 .build_pcms = atihdmi_build_pcms,
131 .init = atihdmi_init,
132 .free = atihdmi_free,
133#ifdef CONFIG_PM
134 .resume = atihdmi_resume,
135#endif
136};
137
138static int patch_atihdmi(struct hda_codec *codec)
139{
140 struct atihdmi_spec *spec;
141
142 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
143 if (spec == NULL)
144 return -ENOMEM;
145
146 codec->spec = spec;
147
148 spec->multiout.num_dacs = 0; /* no analog */
149 spec->multiout.max_channels = 2;
150 spec->multiout.dig_out_nid = 0x2; /* NID for copying analog to digital,
151 * seems to be unused in pure-digital
152 * case. */
153
154 codec->patch_ops = atihdmi_patch_ops;
155
156 return 0;
157}
158
159/*
160 * patch entries
161 */
162struct hda_codec_preset snd_hda_preset_atihdmi[] = {
163 { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
164 {} /* terminator */
165};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index f0e9a9c90780..98b9f16c26ff 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2174,6 +2174,7 @@ static struct hda_board_config alc880_cfg_tbl[] = {
2174 2174
2175 { .modelname = "lg", .config = ALC880_LG }, 2175 { .modelname = "lg", .config = ALC880_LG },
2176 { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG }, 2176 { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG },
2177 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0068, .config = ALC880_LG },
2177 2178
2178 { .modelname = "lg-lw", .config = ALC880_LG_LW }, 2179 { .modelname = "lg-lw", .config = ALC880_LG_LW },
2179 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW }, 2180 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW },
@@ -3105,6 +3106,7 @@ static struct hda_verb alc260_init_verbs[] = {
3105 { } 3106 { }
3106}; 3107};
3107 3108
3109#if 0 /* should be identical with alc260_init_verbs? */
3108static struct hda_verb alc260_hp_init_verbs[] = { 3110static struct hda_verb alc260_hp_init_verbs[] = {
3109 /* Headphone and output */ 3111 /* Headphone and output */
3110 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 3112 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
@@ -3151,6 +3153,7 @@ static struct hda_verb alc260_hp_init_verbs[] = {
3151 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3153 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3152 { } 3154 { }
3153}; 3155};
3156#endif
3154 3157
3155static struct hda_verb alc260_hp_3013_init_verbs[] = { 3158static struct hda_verb alc260_hp_3013_init_verbs[] = {
3156 /* Line out and output */ 3159 /* Line out and output */
@@ -3822,12 +3825,16 @@ static struct hda_board_config alc260_cfg_tbl[] = {
3822 { .modelname = "basic", .config = ALC260_BASIC }, 3825 { .modelname = "basic", .config = ALC260_BASIC },
3823 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb, 3826 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb,
3824 .config = ALC260_BASIC }, /* Sony VAIO */ 3827 .config = ALC260_BASIC }, /* Sony VAIO */
3828 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cc,
3829 .config = ALC260_BASIC }, /* Sony VAIO VGN-S3HP */
3830 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cd,
3831 .config = ALC260_BASIC }, /* Sony VAIO */
3825 { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729, 3832 { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729,
3826 .config = ALC260_BASIC }, /* CTL Travel Master U553W */ 3833 .config = ALC260_BASIC }, /* CTL Travel Master U553W */
3827 { .modelname = "hp", .config = ALC260_HP }, 3834 { .modelname = "hp", .config = ALC260_HP },
3828 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP }, 3835 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP },
3829 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, 3836 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP },
3830 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP }, 3837 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP_3013 },
3831 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 }, 3838 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 },
3832 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP }, 3839 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP },
3833 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP }, 3840 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP },
@@ -3862,7 +3869,7 @@ static struct alc_config_preset alc260_presets[] = {
3862 .mixers = { alc260_base_output_mixer, 3869 .mixers = { alc260_base_output_mixer,
3863 alc260_input_mixer, 3870 alc260_input_mixer,
3864 alc260_capture_alt_mixer }, 3871 alc260_capture_alt_mixer },
3865 .init_verbs = { alc260_hp_init_verbs }, 3872 .init_verbs = { alc260_init_verbs },
3866 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 3873 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
3867 .dac_nids = alc260_dac_nids, 3874 .dac_nids = alc260_dac_nids,
3868 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 3875 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
@@ -4094,21 +4101,6 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
4094 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 4101 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4095 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 4102 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4096 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 4103 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4097 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
4098 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
4099 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
4100 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
4101 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
4102 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
4103 {
4104 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4105 /* .name = "Capture Source", */
4106 .name = "Input Source",
4107 .count = 3,
4108 .info = alc882_mux_enum_info,
4109 .get = alc882_mux_enum_get,
4110 .put = alc882_mux_enum_put,
4111 },
4112 { } /* end */ 4104 { } /* end */
4113}; 4105};
4114 4106
@@ -4342,8 +4334,6 @@ static struct alc_config_preset alc882_presets[] = {
4342 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 4334 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
4343 .dac_nids = alc882_dac_nids, 4335 .dac_nids = alc882_dac_nids,
4344 .dig_out_nid = ALC882_DIGOUT_NID, 4336 .dig_out_nid = ALC882_DIGOUT_NID,
4345 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
4346 .adc_nids = alc882_adc_nids,
4347 .dig_in_nid = ALC882_DIGIN_NID, 4337 .dig_in_nid = ALC882_DIGIN_NID,
4348 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 4338 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
4349 .channel_mode = alc882_ch_modes, 4339 .channel_mode = alc882_ch_modes,
@@ -4355,8 +4345,6 @@ static struct alc_config_preset alc882_presets[] = {
4355 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 4345 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
4356 .dac_nids = alc882_dac_nids, 4346 .dac_nids = alc882_dac_nids,
4357 .dig_out_nid = ALC882_DIGOUT_NID, 4347 .dig_out_nid = ALC882_DIGOUT_NID,
4358 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
4359 .adc_nids = alc882_adc_nids,
4360 .dig_in_nid = ALC882_DIGIN_NID, 4348 .dig_in_nid = ALC882_DIGIN_NID,
4361 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 4349 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
4362 .channel_mode = alc882_sixstack_modes, 4350 .channel_mode = alc882_sixstack_modes,
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 8c440fb98603..36f199442fdc 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -41,6 +41,7 @@
41#define STAC_REF 0 41#define STAC_REF 0
42#define STAC_D945GTP3 1 42#define STAC_D945GTP3 1
43#define STAC_D945GTP5 2 43#define STAC_D945GTP5 2
44#define STAC_MACMINI 3
44 45
45struct sigmatel_spec { 46struct sigmatel_spec {
46 struct snd_kcontrol_new *mixers[4]; 47 struct snd_kcontrol_new *mixers[4];
@@ -52,6 +53,7 @@ struct sigmatel_spec {
52 unsigned int mic_switch: 1; 53 unsigned int mic_switch: 1;
53 unsigned int alt_switch: 1; 54 unsigned int alt_switch: 1;
54 unsigned int hp_detect: 1; 55 unsigned int hp_detect: 1;
56 unsigned int gpio_mute: 1;
55 57
56 /* playback */ 58 /* playback */
57 struct hda_multi_out multiout; 59 struct hda_multi_out multiout;
@@ -293,6 +295,7 @@ static unsigned int *stac922x_brd_tbl[] = {
293 ref922x_pin_configs, 295 ref922x_pin_configs,
294 d945gtp3_pin_configs, 296 d945gtp3_pin_configs,
295 d945gtp5_pin_configs, 297 d945gtp5_pin_configs,
298 NULL, /* STAC_MACMINI */
296}; 299};
297 300
298static struct hda_board_config stac922x_cfg_tbl[] = { 301static struct hda_board_config stac922x_cfg_tbl[] = {
@@ -324,6 +327,9 @@ static struct hda_board_config stac922x_cfg_tbl[] = {
324 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 327 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
325 .pci_subdevice = 0x0417, 328 .pci_subdevice = 0x0417,
326 .config = STAC_D945GTP5 }, /* Intel D975XBK - 5 Stack */ 329 .config = STAC_D945GTP5 }, /* Intel D975XBK - 5 Stack */
330 { .pci_subvendor = 0x8384,
331 .pci_subdevice = 0x7680,
332 .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */
327 {} /* terminator */ 333 {} /* terminator */
328}; 334};
329 335
@@ -841,6 +847,19 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
841 } 847 }
842 } 848 }
843 849
850 if (imux->num_items == 1) {
851 /*
852 * Set the current input for the muxes.
853 * The STAC9221 has two input muxes with identical source
854 * NID lists. Hopefully this won't get confused.
855 */
856 for (i = 0; i < spec->num_muxes; i++) {
857 snd_hda_codec_write(codec, spec->mux_nids[i], 0,
858 AC_VERB_SET_CONNECT_SEL,
859 imux->items[0].index);
860 }
861 }
862
844 return 0; 863 return 0;
845} 864}
846 865
@@ -946,6 +965,45 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
946 return 1; 965 return 1;
947} 966}
948 967
968/*
969 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
970 * funky external mute control using GPIO pins.
971 */
972
973static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted)
974{
975 unsigned int gpiostate, gpiomask, gpiodir;
976
977 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
978 AC_VERB_GET_GPIO_DATA, 0);
979
980 if (!muted)
981 gpiostate |= (1 << pin);
982 else
983 gpiostate &= ~(1 << pin);
984
985 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
986 AC_VERB_GET_GPIO_MASK, 0);
987 gpiomask |= (1 << pin);
988
989 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
990 AC_VERB_GET_GPIO_DIRECTION, 0);
991 gpiodir |= (1 << pin);
992
993 /* AppleHDA seems to do this -- WTF is this verb?? */
994 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
995
996 snd_hda_codec_write(codec, codec->afg, 0,
997 AC_VERB_SET_GPIO_MASK, gpiomask);
998 snd_hda_codec_write(codec, codec->afg, 0,
999 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1000
1001 msleep(1);
1002
1003 snd_hda_codec_write(codec, codec->afg, 0,
1004 AC_VERB_SET_GPIO_DATA, gpiostate);
1005}
1006
949static int stac92xx_init(struct hda_codec *codec) 1007static int stac92xx_init(struct hda_codec *codec)
950{ 1008{
951 struct sigmatel_spec *spec = codec->spec; 1009 struct sigmatel_spec *spec = codec->spec;
@@ -982,6 +1040,11 @@ static int stac92xx_init(struct hda_codec *codec)
982 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, 1040 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
983 AC_PINCTL_IN_EN); 1041 AC_PINCTL_IN_EN);
984 1042
1043 if (spec->gpio_mute) {
1044 stac922x_gpio_mute(codec, 0, 0);
1045 stac922x_gpio_mute(codec, 1, 0);
1046 }
1047
985 return 0; 1048 return 0;
986} 1049}
987 1050
@@ -1132,7 +1195,7 @@ static int patch_stac922x(struct hda_codec *codec)
1132 spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); 1195 spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl);
1133 if (spec->board_config < 0) 1196 if (spec->board_config < 0)
1134 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, using BIOS defaults\n"); 1197 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, using BIOS defaults\n");
1135 else { 1198 else if (stac922x_brd_tbl[spec->board_config] != NULL) {
1136 spec->num_pins = 10; 1199 spec->num_pins = 10;
1137 spec->pin_nids = stac922x_pin_nids; 1200 spec->pin_nids = stac922x_pin_nids;
1138 spec->pin_configs = stac922x_brd_tbl[spec->board_config]; 1201 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
@@ -1154,6 +1217,9 @@ static int patch_stac922x(struct hda_codec *codec)
1154 return err; 1217 return err;
1155 } 1218 }
1156 1219
1220 if (spec->board_config == STAC_MACMINI)
1221 spec->gpio_mute = 1;
1222
1157 codec->patch_ops = stac92xx_patch_ops; 1223 codec->patch_ops = stac92xx_patch_ops;
1158 1224
1159 return 0; 1225 return 0;
@@ -1262,13 +1328,13 @@ static int vaio_master_sw_put(struct snd_kcontrol *kcontrol,
1262 int change; 1328 int change;
1263 1329
1264 change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, 1330 change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0,
1265 0x80, valp[0] & 0x80); 1331 0x80, (valp[0] ? 0 : 0x80));
1266 change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, 1332 change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0,
1267 0x80, valp[1] & 0x80); 1333 0x80, (valp[1] ? 0 : 0x80));
1268 snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, 1334 snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
1269 0x80, valp[0] & 0x80); 1335 0x80, (valp[0] ? 0 : 0x80));
1270 snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, 1336 snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
1271 0x80, valp[1] & 0x80); 1337 0x80, (valp[1] ? 0 : 0x80));
1272 return change; 1338 return change;
1273} 1339}
1274 1340
@@ -1370,6 +1436,12 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
1370 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x }, 1436 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
1371 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x }, 1437 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
1372 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x }, 1438 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
1439 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac922x },
1440 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac922x },
1441 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac922x },
1442 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac922x },
1443 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac922x },
1444 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac922x },
1373 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x }, 1445 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
1374 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x }, 1446 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
1375 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x }, 1447 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 336dc489aee1..ca74f5b85f42 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -1281,9 +1281,15 @@ static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
1281 1281
1282 tmp2 = tmp = snd_ice1712_gpio_read(ice); 1282 tmp2 = tmp = snd_ice1712_gpio_read(ice);
1283 if (enable) 1283 if (enable)
1284 tmp |= AUREON_HP_SEL; 1284 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT)
1285 tmp |= AUREON_HP_SEL;
1286 else
1287 tmp |= PRODIGY_HP_SEL;
1285 else 1288 else
1286 tmp &= ~ AUREON_HP_SEL; 1289 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT)
1290 tmp &= ~ AUREON_HP_SEL;
1291 else
1292 tmp &= ~ PRODIGY_HP_SEL;
1287 if (tmp != tmp2) { 1293 if (tmp != tmp2) {
1288 snd_ice1712_gpio_write(ice, tmp); 1294 snd_ice1712_gpio_write(ice, tmp);
1289 return 1; 1295 return 1;
@@ -2079,16 +2085,16 @@ static unsigned char prodigy71_eeprom[] __devinitdata = {
2079}; 2085};
2080 2086
2081static unsigned char prodigy71lt_eeprom[] __devinitdata = { 2087static unsigned char prodigy71lt_eeprom[] __devinitdata = {
2082 0x0b, /* SYSCINF: clock 512, spdif-in/ADC, 4DACs */ 2088 0x4b, /* SYSCINF: clock 512, spdif-in/ADC, 4DACs */
2083 0x80, /* ACLINK: I2S */ 2089 0x80, /* ACLINK: I2S */
2084 0xfc, /* I2S: vol, 96k, 24bit, 192k */ 2090 0xfc, /* I2S: vol, 96k, 24bit, 192k */
2085 0xc3, /* SPDUF: out-en, out-int */ 2091 0xc3, /* SPDIF: out-en, out-int, spdif-in */
2086 0x00, /* GPIO_DIR */ 2092 0xff, /* GPIO_DIR */
2087 0x07, /* GPIO_DIR1 */ 2093 0xff, /* GPIO_DIR1 */
2088 0x00, /* GPIO_DIR2 */ 2094 0x5f, /* GPIO_DIR2 */
2089 0xff, /* GPIO_MASK */ 2095 0x00, /* GPIO_MASK */
2090 0xf8, /* GPIO_MASK1 */ 2096 0x00, /* GPIO_MASK1 */
2091 0xff, /* GPIO_MASK2 */ 2097 0x00, /* GPIO_MASK2 */
2092 0x00, /* GPIO_STATE */ 2098 0x00, /* GPIO_STATE */
2093 0x00, /* GPIO_STATE1 */ 2099 0x00, /* GPIO_STATE1 */
2094 0x00, /* GPIO_STATE2 */ 2100 0x00, /* GPIO_STATE2 */
diff --git a/sound/pci/ice1712/aureon.h b/sound/pci/ice1712/aureon.h
index 98a6752280f2..3b7bea656c57 100644
--- a/sound/pci/ice1712/aureon.h
+++ b/sound/pci/ice1712/aureon.h
@@ -58,5 +58,6 @@ extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[];
58#define PRODIGY_WM_CS (1 << 8) 58#define PRODIGY_WM_CS (1 << 8)
59#define PRODIGY_SPI_MOSI (1 << 10) 59#define PRODIGY_SPI_MOSI (1 << 10)
60#define PRODIGY_SPI_CLK (1 << 9) 60#define PRODIGY_SPI_CLK (1 << 9)
61#define PRODIGY_HP_SEL (1 << 5)
61 62
62#endif /* __SOUND_AUREON_H */ 63#endif /* __SOUND_AUREON_H */
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index 2c529e741384..b135389fec6c 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -1031,6 +1031,9 @@ struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
1031 .model = "dmx6fire", 1031 .model = "dmx6fire",
1032 .chip_init = snd_ice1712_ews_init, 1032 .chip_init = snd_ice1712_ews_init,
1033 .build_controls = snd_ice1712_ews_add_controls, 1033 .build_controls = snd_ice1712_ews_add_controls,
1034 .mpu401_1_name = "MIDI-Front DMX6fire",
1035 .mpu401_2_name = "Wavetable DMX6fire",
1036 .mpu401_2_info_flags = MPU401_INFO_OUTPUT,
1034 }, 1037 },
1035 { } /* terminator */ 1038 { } /* terminator */
1036}; 1039};
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index c56793b381e2..845907159b74 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -61,7 +61,6 @@
61#include <sound/core.h> 61#include <sound/core.h>
62#include <sound/cs8427.h> 62#include <sound/cs8427.h>
63#include <sound/info.h> 63#include <sound/info.h>
64#include <sound/mpu401.h>
65#include <sound/initval.h> 64#include <sound/initval.h>
66 65
67#include <sound/asoundef.h> 66#include <sound/asoundef.h>
@@ -1596,7 +1595,7 @@ static void __devinit snd_ice1712_proc_init(struct snd_ice1712 * ice)
1596 struct snd_info_entry *entry; 1595 struct snd_info_entry *entry;
1597 1596
1598 if (! snd_card_proc_new(ice->card, "ice1712", &entry)) 1597 if (! snd_card_proc_new(ice->card, "ice1712", &entry))
1599 snd_info_set_text_ops(entry, ice, 1024, snd_ice1712_proc_read); 1598 snd_info_set_text_ops(entry, ice, snd_ice1712_proc_read);
1600} 1599}
1601 1600
1602/* 1601/*
@@ -2398,13 +2397,14 @@ static int __devinit snd_ice1712_chip_init(struct snd_ice1712 *ice)
2398 udelay(200); 2397 udelay(200);
2399 outb(ICE1712_NATIVE, ICEREG(ice, CONTROL)); 2398 outb(ICE1712_NATIVE, ICEREG(ice, CONTROL));
2400 udelay(200); 2399 udelay(200);
2401 if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DMX6FIRE && !ice->dxr_enable) { 2400 if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DMX6FIRE &&
2402 /* Limit active ADCs and DACs to 6; */ 2401 !ice->dxr_enable)
2403 /* Note: DXR extension not supported */ 2402 /* Set eeprom value to limit active ADCs and DACs to 6;
2404 pci_write_config_byte(ice->pci, 0x60, 0x2a); 2403 * Also disable AC97 as no hardware in standard 6fire card/box
2405 } else { 2404 * Note: DXR extensions are not currently supported
2406 pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]); 2405 */
2407 } 2406 ice->eeprom.data[ICE_EEP1_CODEC] = 0x3a;
2407 pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]);
2408 pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]); 2408 pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]);
2409 pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]); 2409 pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]);
2410 pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]); 2410 pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]);
@@ -2737,21 +2737,38 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2737 2737
2738 if (! c->no_mpu401) { 2738 if (! c->no_mpu401) {
2739 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, 2739 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
2740 ICEREG(ice, MPU1_CTRL), 1, 2740 ICEREG(ice, MPU1_CTRL),
2741 (c->mpu401_1_info_flags |
2742 MPU401_INFO_INTEGRATED),
2741 ice->irq, 0, 2743 ice->irq, 0,
2742 &ice->rmidi[0])) < 0) { 2744 &ice->rmidi[0])) < 0) {
2743 snd_card_free(card); 2745 snd_card_free(card);
2744 return err; 2746 return err;
2745 } 2747 }
2746 2748 if (c->mpu401_1_name)
2747 if (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) 2749 /* Prefered name available in card_info */
2750 snprintf(ice->rmidi[0]->name,
2751 sizeof(ice->rmidi[0]->name),
2752 "%s %d", c->mpu401_1_name, card->number);
2753
2754 if (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) {
2755 /* 2nd port used */
2748 if ((err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712, 2756 if ((err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712,
2749 ICEREG(ice, MPU2_CTRL), 1, 2757 ICEREG(ice, MPU2_CTRL),
2758 (c->mpu401_2_info_flags |
2759 MPU401_INFO_INTEGRATED),
2750 ice->irq, 0, 2760 ice->irq, 0,
2751 &ice->rmidi[1])) < 0) { 2761 &ice->rmidi[1])) < 0) {
2752 snd_card_free(card); 2762 snd_card_free(card);
2753 return err; 2763 return err;
2754 } 2764 }
2765 if (c->mpu401_2_name)
2766 /* Prefered name available in card_info */
2767 snprintf(ice->rmidi[1]->name,
2768 sizeof(ice->rmidi[1]->name),
2769 "%s %d", c->mpu401_2_name,
2770 card->number);
2771 }
2755 } 2772 }
2756 2773
2757 snd_ice1712_set_input_clock_source(ice, 0); 2774 snd_ice1712_set_input_clock_source(ice, 0);
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 053f8e56fd68..ce27eac40d4e 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -29,6 +29,7 @@
29#include <sound/ak4xxx-adda.h> 29#include <sound/ak4xxx-adda.h>
30#include <sound/ak4114.h> 30#include <sound/ak4114.h>
31#include <sound/pcm.h> 31#include <sound/pcm.h>
32#include <sound/mpu401.h>
32 33
33 34
34/* 35/*
@@ -495,6 +496,10 @@ struct snd_ice1712_card_info {
495 int (*chip_init)(struct snd_ice1712 *); 496 int (*chip_init)(struct snd_ice1712 *);
496 int (*build_controls)(struct snd_ice1712 *); 497 int (*build_controls)(struct snd_ice1712 *);
497 unsigned int no_mpu401: 1; 498 unsigned int no_mpu401: 1;
499 unsigned int mpu401_1_info_flags;
500 unsigned int mpu401_2_info_flags;
501 const char *mpu401_1_name;
502 const char *mpu401_2_name;
498 unsigned int eeprom_size; 503 unsigned int eeprom_size;
499 unsigned char *eeprom_data; 504 unsigned char *eeprom_data;
500}; 505};
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index b1c007e022d2..34a58c629f47 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -1293,7 +1293,7 @@ static void __devinit snd_vt1724_proc_init(struct snd_ice1712 * ice)
1293 struct snd_info_entry *entry; 1293 struct snd_info_entry *entry;
1294 1294
1295 if (! snd_card_proc_new(ice->card, "ice1724", &entry)) 1295 if (! snd_card_proc_new(ice->card, "ice1724", &entry))
1296 snd_info_set_text_ops(entry, ice, 1024, snd_vt1724_proc_read); 1296 snd_info_set_text_ops(entry, ice, snd_vt1724_proc_read);
1297} 1297}
1298 1298
1299/* 1299/*
@@ -2388,7 +2388,8 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2388 if (! c->no_mpu401) { 2388 if (! c->no_mpu401) {
2389 if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) { 2389 if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) {
2390 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, 2390 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
2391 ICEREG1724(ice, MPU_CTRL), 1, 2391 ICEREG1724(ice, MPU_CTRL),
2392 MPU401_INFO_INTEGRATED,
2392 ice->irq, 0, 2393 ice->irq, 0,
2393 &ice->rmidi[0])) < 0) { 2394 &ice->rmidi[0])) < 0) {
2394 snd_card_free(card); 2395 snd_card_free(card);
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index d23fb3fc2133..0efcad9260a5 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -680,9 +680,8 @@ static void wm_proc_init(struct snd_ice1712 *ice)
680{ 680{
681 struct snd_info_entry *entry; 681 struct snd_info_entry *entry;
682 if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) { 682 if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) {
683 snd_info_set_text_ops(entry, ice, 1024, wm_proc_regs_read); 683 snd_info_set_text_ops(entry, ice, wm_proc_regs_read);
684 entry->mode |= S_IWUSR; 684 entry->mode |= S_IWUSR;
685 entry->c.text.write_size = 1024;
686 entry->c.text.write = wm_proc_regs_write; 685 entry->c.text.write = wm_proc_regs_write;
687 } 686 }
688} 687}
@@ -705,9 +704,8 @@ static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buff
705static void cs_proc_init(struct snd_ice1712 *ice) 704static void cs_proc_init(struct snd_ice1712 *ice)
706{ 705{
707 struct snd_info_entry *entry; 706 struct snd_info_entry *entry;
708 if (! snd_card_proc_new(ice->card, "cs_codec", &entry)) { 707 if (! snd_card_proc_new(ice->card, "cs_codec", &entry))
709 snd_info_set_text_ops(entry, ice, 1024, cs_proc_regs_read); 708 snd_info_set_text_ops(entry, ice, cs_proc_regs_read);
710 }
711} 709}
712 710
713 711
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 0df7602568e2..edc14475ef82 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -66,7 +66,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
66 66
67static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ 67static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
68static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ 68static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
69static int ac97_clock = 0; 69static int ac97_clock;
70static char *ac97_quirk; 70static char *ac97_quirk;
71static int buggy_semaphore; 71static int buggy_semaphore;
72static int buggy_irq = -1; /* auto-check */ 72static int buggy_irq = -1; /* auto-check */
@@ -1807,6 +1807,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
1807 }, 1807 },
1808 { 1808 {
1809 .subvendor = 0x1028, 1809 .subvendor = 0x1028,
1810 .subdevice = 0x014e,
1811 .name = "Dell D800", /* STAC9750/51 */
1812 .type = AC97_TUNE_HP_ONLY
1813 },
1814 {
1815 .subvendor = 0x1028,
1810 .subdevice = 0x0163, 1816 .subdevice = 0x0163,
1811 .name = "Dell Unknown", /* STAC9750/51 */ 1817 .name = "Dell Unknown", /* STAC9750/51 */
1812 .type = AC97_TUNE_HP_ONLY 1818 .type = AC97_TUNE_HP_ONLY
@@ -2645,7 +2651,7 @@ static void __devinit snd_intel8x0_proc_init(struct intel8x0 * chip)
2645 struct snd_info_entry *entry; 2651 struct snd_info_entry *entry;
2646 2652
2647 if (! snd_card_proc_new(chip->card, "intel8x0", &entry)) 2653 if (! snd_card_proc_new(chip->card, "intel8x0", &entry))
2648 snd_info_set_text_ops(entry, chip, 1024, snd_intel8x0_proc_read); 2654 snd_info_set_text_ops(entry, chip, snd_intel8x0_proc_read);
2649} 2655}
2650#else 2656#else
2651#define snd_intel8x0_proc_init(x) 2657#define snd_intel8x0_proc_init(x)
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 720635f0cb81..24703d75b65a 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -59,7 +59,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
59 59
60static int index = -2; /* Exclude the first card */ 60static int index = -2; /* Exclude the first card */
61static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ 61static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
62static int ac97_clock = 0; 62static int ac97_clock;
63 63
64module_param(index, int, 0444); 64module_param(index, int, 0444);
65MODULE_PARM_DESC(index, "Index value for Intel i8x0 modemcard."); 65MODULE_PARM_DESC(index, "Index value for Intel i8x0 modemcard.");
@@ -1092,7 +1092,7 @@ static void __devinit snd_intel8x0m_proc_init(struct intel8x0m * chip)
1092 struct snd_info_entry *entry; 1092 struct snd_info_entry *entry;
1093 1093
1094 if (! snd_card_proc_new(chip->card, "intel8x0m", &entry)) 1094 if (! snd_card_proc_new(chip->card, "intel8x0m", &entry))
1095 snd_info_set_text_ops(entry, chip, 1024, snd_intel8x0m_proc_read); 1095 snd_info_set_text_ops(entry, chip, snd_intel8x0m_proc_read);
1096} 1096}
1097#else /* !CONFIG_PROC_FS */ 1097#else /* !CONFIG_PROC_FS */
1098#define snd_intel8x0m_proc_init(chip) 1098#define snd_intel8x0m_proc_init(chip)
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index e39fad1a4200..6e97932de34f 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2085,7 +2085,7 @@ static void __devinit snd_korg1212_proc_init(struct snd_korg1212 *korg1212)
2085 struct snd_info_entry *entry; 2085 struct snd_info_entry *entry;
2086 2086
2087 if (! snd_card_proc_new(korg1212->card, "korg1212", &entry)) 2087 if (! snd_card_proc_new(korg1212->card, "korg1212", &entry))
2088 snd_info_set_text_ops(entry, korg1212, 1024, snd_korg1212_proc_read); 2088 snd_info_set_text_ops(entry, korg1212, snd_korg1212_proc_read);
2089} 2089}
2090 2090
2091static int 2091static int
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 1928e06b6d82..1c344fbd964d 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -2861,7 +2861,8 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2861#if 0 /* TODO: not supported yet */ 2861#if 0 /* TODO: not supported yet */
2862 /* TODO enable MIDI IRQ and I/O */ 2862 /* TODO enable MIDI IRQ and I/O */
2863 err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401, 2863 err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401,
2864 chip->iobase + MPU401_DATA_PORT, 1, 2864 chip->iobase + MPU401_DATA_PORT,
2865 MPU401_INFO_INTEGRATED,
2865 chip->irq, 0, &chip->rmidi); 2866 chip->irq, 0, &chip->rmidi);
2866 if (err < 0) 2867 if (err < 0)
2867 printk(KERN_WARNING "maestro3: no MIDI support.\n"); 2868 printk(KERN_WARNING "maestro3: no MIDI support.\n");
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 09cc0786495a..366c4a7e65c6 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1244,7 +1244,6 @@ static void __devinit snd_mixart_proc_init(struct snd_mixart *chip)
1244 /* text interface to read perf and temp meters */ 1244 /* text interface to read perf and temp meters */
1245 if (! snd_card_proc_new(chip->card, "board_info", &entry)) { 1245 if (! snd_card_proc_new(chip->card, "board_info", &entry)) {
1246 entry->private_data = chip; 1246 entry->private_data = chip;
1247 entry->c.text.read_size = 1024;
1248 entry->c.text.read = snd_mixart_proc_read; 1247 entry->c.text.read = snd_mixart_proc_read;
1249 } 1248 }
1250 1249
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index dafa2235abaa..8198884b51ee 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1150,9 +1150,9 @@ static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip)
1150 struct snd_info_entry *entry; 1150 struct snd_info_entry *entry;
1151 1151
1152 if (! snd_card_proc_new(chip->card, "info", &entry)) 1152 if (! snd_card_proc_new(chip->card, "info", &entry))
1153 snd_info_set_text_ops(entry, chip, 1024, pcxhr_proc_info); 1153 snd_info_set_text_ops(entry, chip, pcxhr_proc_info);
1154 if (! snd_card_proc_new(chip->card, "sync", &entry)) 1154 if (! snd_card_proc_new(chip->card, "sync", &entry))
1155 snd_info_set_text_ops(entry, chip, 1024, pcxhr_proc_sync); 1155 snd_info_set_text_ops(entry, chip, pcxhr_proc_sync);
1156} 1156}
1157/* end of proc interface */ 1157/* end of proc interface */
1158 1158
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index d8cc985d7241..5618ec9740bd 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1836,11 +1836,11 @@ static int snd_riptide_free(struct snd_riptide *chip)
1836 UNSET_GRESET(cif->hwport); 1836 UNSET_GRESET(cif->hwport);
1837 kfree(chip->cif); 1837 kfree(chip->cif);
1838 } 1838 }
1839 if (chip->irq >= 0)
1840 free_irq(chip->irq, chip);
1839 if (chip->fw_entry) 1841 if (chip->fw_entry)
1840 release_firmware(chip->fw_entry); 1842 release_firmware(chip->fw_entry);
1841 release_and_free_resource(chip->res_port); 1843 release_and_free_resource(chip->res_port);
1842 if (chip->irq >= 0)
1843 free_irq(chip->irq, chip);
1844 kfree(chip); 1844 kfree(chip);
1845 return 0; 1845 return 0;
1846} 1846}
@@ -1992,7 +1992,7 @@ static void __devinit snd_riptide_proc_init(struct snd_riptide *chip)
1992 struct snd_info_entry *entry; 1992 struct snd_info_entry *entry;
1993 1993
1994 if (!snd_card_proc_new(chip->card, "riptide", &entry)) 1994 if (!snd_card_proc_new(chip->card, "riptide", &entry))
1995 snd_info_set_text_ops(entry, chip, 4096, snd_riptide_proc_read); 1995 snd_info_set_text_ops(entry, chip, snd_riptide_proc_read);
1996} 1996}
1997 1997
1998static int __devinit snd_riptide_mixer(struct snd_riptide *chip) 1998static int __devinit snd_riptide_mixer(struct snd_riptide *chip)
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 55b1d4838d97..2cb9fe98db2f 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1368,18 +1368,18 @@ static int __devinit snd_rme32_create(struct rme32 * rme32)
1368 return err; 1368 return err;
1369 rme32->port = pci_resource_start(rme32->pci, 0); 1369 rme32->port = pci_resource_start(rme32->pci, 0);
1370 1370
1371 if (request_irq(pci->irq, snd_rme32_interrupt, SA_INTERRUPT | SA_SHIRQ, "RME32", (void *) rme32)) {
1372 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1373 return -EBUSY;
1374 }
1375 rme32->irq = pci->irq;
1376
1377 if ((rme32->iobase = ioremap_nocache(rme32->port, RME32_IO_SIZE)) == 0) { 1371 if ((rme32->iobase = ioremap_nocache(rme32->port, RME32_IO_SIZE)) == 0) {
1378 snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", 1372 snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n",
1379 rme32->port, rme32->port + RME32_IO_SIZE - 1); 1373 rme32->port, rme32->port + RME32_IO_SIZE - 1);
1380 return -ENOMEM; 1374 return -ENOMEM;
1381 } 1375 }
1382 1376
1377 if (request_irq(pci->irq, snd_rme32_interrupt, SA_INTERRUPT | SA_SHIRQ, "RME32", (void *) rme32)) {
1378 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1379 return -EBUSY;
1380 }
1381 rme32->irq = pci->irq;
1382
1383 /* read the card's revision number */ 1383 /* read the card's revision number */
1384 pci_read_config_byte(pci, 8, &rme32->rev); 1384 pci_read_config_byte(pci, 8, &rme32->rev);
1385 1385
@@ -1578,7 +1578,7 @@ static void __devinit snd_rme32_proc_init(struct rme32 * rme32)
1578 struct snd_info_entry *entry; 1578 struct snd_info_entry *entry;
1579 1579
1580 if (! snd_card_proc_new(rme32->card, "rme32", &entry)) 1580 if (! snd_card_proc_new(rme32->card, "rme32", &entry))
1581 snd_info_set_text_ops(entry, rme32, 1024, snd_rme32_proc_read); 1581 snd_info_set_text_ops(entry, rme32, snd_rme32_proc_read);
1582} 1582}
1583 1583
1584/* 1584/*
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 3c1bc533d511..991cb18c14f3 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -1151,6 +1151,25 @@ static struct snd_pcm_hw_constraint_list hw_constraints_period_bytes = {
1151 .mask = 0 1151 .mask = 0
1152}; 1152};
1153 1153
1154static void
1155rme96_set_buffer_size_constraint(struct rme96 *rme96,
1156 struct snd_pcm_runtime *runtime)
1157{
1158 unsigned int size;
1159
1160 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1161 RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
1162 if ((size = rme96->playback_periodsize) != 0 ||
1163 (size = rme96->capture_periodsize) != 0)
1164 snd_pcm_hw_constraint_minmax(runtime,
1165 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1166 size, size);
1167 else
1168 snd_pcm_hw_constraint_list(runtime, 0,
1169 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1170 &hw_constraints_period_bytes);
1171}
1172
1154static int 1173static int
1155snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream) 1174snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
1156{ 1175{
@@ -1180,8 +1199,7 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
1180 runtime->hw.rate_min = rate; 1199 runtime->hw.rate_min = rate;
1181 runtime->hw.rate_max = rate; 1200 runtime->hw.rate_max = rate;
1182 } 1201 }
1183 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); 1202 rme96_set_buffer_size_constraint(rme96, runtime);
1184 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
1185 1203
1186 rme96->wcreg_spdif_stream = rme96->wcreg_spdif; 1204 rme96->wcreg_spdif_stream = rme96->wcreg_spdif;
1187 rme96->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 1205 rme96->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
@@ -1219,9 +1237,7 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream)
1219 rme96->capture_substream = substream; 1237 rme96->capture_substream = substream;
1220 spin_unlock_irq(&rme96->lock); 1238 spin_unlock_irq(&rme96->lock);
1221 1239
1222 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); 1240 rme96_set_buffer_size_constraint(rme96, runtime);
1223 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
1224
1225 return 0; 1241 return 0;
1226} 1242}
1227 1243
@@ -1254,8 +1270,7 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream)
1254 runtime->hw.rate_min = rate; 1270 runtime->hw.rate_min = rate;
1255 runtime->hw.rate_max = rate; 1271 runtime->hw.rate_max = rate;
1256 } 1272 }
1257 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); 1273 rme96_set_buffer_size_constraint(rme96, runtime);
1258 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
1259 return 0; 1274 return 0;
1260} 1275}
1261 1276
@@ -1291,8 +1306,7 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream)
1291 rme96->capture_substream = substream; 1306 rme96->capture_substream = substream;
1292 spin_unlock_irq(&rme96->lock); 1307 spin_unlock_irq(&rme96->lock);
1293 1308
1294 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); 1309 rme96_set_buffer_size_constraint(rme96, runtime);
1295 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
1296 return 0; 1310 return 0;
1297} 1311}
1298 1312
@@ -1569,17 +1583,17 @@ snd_rme96_create(struct rme96 *rme96)
1569 return err; 1583 return err;
1570 rme96->port = pci_resource_start(rme96->pci, 0); 1584 rme96->port = pci_resource_start(rme96->pci, 0);
1571 1585
1586 if ((rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {
1587 snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
1588 return -ENOMEM;
1589 }
1590
1572 if (request_irq(pci->irq, snd_rme96_interrupt, SA_INTERRUPT|SA_SHIRQ, "RME96", (void *)rme96)) { 1591 if (request_irq(pci->irq, snd_rme96_interrupt, SA_INTERRUPT|SA_SHIRQ, "RME96", (void *)rme96)) {
1573 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1592 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1574 return -EBUSY; 1593 return -EBUSY;
1575 } 1594 }
1576 rme96->irq = pci->irq; 1595 rme96->irq = pci->irq;
1577 1596
1578 if ((rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {
1579 snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
1580 return -ENOMEM;
1581 }
1582
1583 /* read the card's revision number */ 1597 /* read the card's revision number */
1584 pci_read_config_byte(pci, 8, &rme96->rev); 1598 pci_read_config_byte(pci, 8, &rme96->rev);
1585 1599
@@ -1805,7 +1819,7 @@ snd_rme96_proc_init(struct rme96 *rme96)
1805 struct snd_info_entry *entry; 1819 struct snd_info_entry *entry;
1806 1820
1807 if (! snd_card_proc_new(rme96->card, "rme96", &entry)) 1821 if (! snd_card_proc_new(rme96->card, "rme96", &entry))
1808 snd_info_set_text_ops(entry, rme96, 1024, snd_rme96_proc_read); 1822 snd_info_set_text_ops(entry, rme96, snd_rme96_proc_read);
1809} 1823}
1810 1824
1811/* 1825/*
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 61f82f0d5cc6..eaf3c22449ad 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -389,7 +389,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
389 389
390/* use hotplug firmeare loader? */ 390/* use hotplug firmeare loader? */
391#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) 391#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
392#ifndef HDSP_USE_HWDEP_LOADER 392#if !defined(HDSP_USE_HWDEP_LOADER) && !defined(CONFIG_SND_HDSP)
393#define HDSP_FW_LOADER 393#define HDSP_FW_LOADER
394#endif 394#endif
395#endif 395#endif
@@ -3169,9 +3169,10 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3169 char *clock_source; 3169 char *clock_source;
3170 int x; 3170 int x;
3171 3171
3172 if (hdsp_check_for_iobox (hdsp)) 3172 if (hdsp_check_for_iobox (hdsp)) {
3173 snd_iprintf(buffer, "No I/O box connected.\nPlease connect one and upload firmware.\n"); 3173 snd_iprintf(buffer, "No I/O box connected.\nPlease connect one and upload firmware.\n");
3174 return; 3174 return;
3175 }
3175 3176
3176 if (hdsp_check_for_firmware(hdsp, 0)) { 3177 if (hdsp_check_for_firmware(hdsp, 0)) {
3177 if (hdsp->state & HDSP_FirmwareCached) { 3178 if (hdsp->state & HDSP_FirmwareCached) {
@@ -3470,7 +3471,7 @@ static void __devinit snd_hdsp_proc_init(struct hdsp *hdsp)
3470 struct snd_info_entry *entry; 3471 struct snd_info_entry *entry;
3471 3472
3472 if (! snd_card_proc_new(hdsp->card, "hdsp", &entry)) 3473 if (! snd_card_proc_new(hdsp->card, "hdsp", &entry))
3473 snd_info_set_text_ops(entry, hdsp, 1024, snd_hdsp_proc_read); 3474 snd_info_set_text_ops(entry, hdsp, snd_hdsp_proc_read);
3474} 3475}
3475 3476
3476static void snd_hdsp_free_buffers(struct hdsp *hdsp) 3477static void snd_hdsp_free_buffers(struct hdsp *hdsp)
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 722b9e6ce54a..bba1615504d3 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -2489,7 +2489,7 @@ static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm)
2489 struct snd_info_entry *entry; 2489 struct snd_info_entry *entry;
2490 2490
2491 if (!snd_card_proc_new(hdspm->card, "hdspm", &entry)) 2491 if (!snd_card_proc_new(hdspm->card, "hdspm", &entry))
2492 snd_info_set_text_ops(entry, hdspm, 1024, 2492 snd_info_set_text_ops(entry, hdspm,
2493 snd_hdspm_proc_read); 2493 snd_hdspm_proc_read);
2494} 2494}
2495 2495
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 75d6406303d3..3b945e8c1b15 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -41,7 +41,7 @@
41static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 41static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
42static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 42static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
43static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 43static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
44static int precise_ptr[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* Enable precise pointer */ 44static int precise_ptr[SNDRV_CARDS]; /* Enable precise pointer */
45 45
46module_param_array(index, int, NULL, 0444); 46module_param_array(index, int, NULL, 0444);
47MODULE_PARM_DESC(index, "Index value for RME Digi9652 (Hammerfall) soundcard."); 47MODULE_PARM_DESC(index, "Index value for RME Digi9652 (Hammerfall) soundcard.");
@@ -1787,7 +1787,7 @@ static void __devinit snd_rme9652_proc_init(struct snd_rme9652 *rme9652)
1787 struct snd_info_entry *entry; 1787 struct snd_info_entry *entry;
1788 1788
1789 if (! snd_card_proc_new(rme9652->card, "rme9652", &entry)) 1789 if (! snd_card_proc_new(rme9652->card, "rme9652", &entry))
1790 snd_info_set_text_ops(entry, rme9652, 1024, snd_rme9652_proc_read); 1790 snd_info_set_text_ops(entry, rme9652, snd_rme9652_proc_read);
1791} 1791}
1792 1792
1793static void snd_rme9652_free_buffers(struct snd_rme9652 *rme9652) 1793static void snd_rme9652_free_buffers(struct snd_rme9652 *rme9652)
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 91f8bf3ae9fa..dcf402948347 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -54,8 +54,8 @@ MODULE_SUPPORTED_DEVICE("{{S3,SonicVibes PCI}}");
54static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 54static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
55static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 55static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
56static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 56static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
57static int reverb[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 57static int reverb[SNDRV_CARDS];
58static int mge[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 58static int mge[SNDRV_CARDS];
59static unsigned int dmaio = 0x7a00; /* DDMA i/o address */ 59static unsigned int dmaio = 0x7a00; /* DDMA i/o address */
60 60
61module_param_array(index, int, NULL, 0444); 61module_param_array(index, int, NULL, 0444);
@@ -1144,7 +1144,7 @@ static void __devinit snd_sonicvibes_proc_init(struct sonicvibes * sonic)
1144 struct snd_info_entry *entry; 1144 struct snd_info_entry *entry;
1145 1145
1146 if (! snd_card_proc_new(sonic->card, "sonicvibes", &entry)) 1146 if (! snd_card_proc_new(sonic->card, "sonicvibes", &entry))
1147 snd_info_set_text_ops(entry, sonic, 1024, snd_sonicvibes_proc_read); 1147 snd_info_set_text_ops(entry, sonic, snd_sonicvibes_proc_read);
1148} 1148}
1149 1149
1150/* 1150/*
@@ -1456,7 +1456,7 @@ static int __devinit snd_sonic_probe(struct pci_dev *pci,
1456 return err; 1456 return err;
1457 } 1457 }
1458 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES, 1458 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES,
1459 sonic->midi_port, 1, 1459 sonic->midi_port, MPU401_INFO_INTEGRATED,
1460 sonic->irq, 0, 1460 sonic->irq, 0,
1461 &midi_uart)) < 0) { 1461 &midi_uart)) < 0) {
1462 snd_card_free(card); 1462 snd_card_free(card);
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 9624a5f2b875..5629b7eba96d 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -148,7 +148,8 @@ static int __devinit snd_trident_probe(struct pci_dev *pci,
148 } 148 }
149 if (trident->device != TRIDENT_DEVICE_ID_SI7018 && 149 if (trident->device != TRIDENT_DEVICE_ID_SI7018 &&
150 (err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE, 150 (err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE,
151 trident->midi_port, 1, 151 trident->midi_port,
152 MPU401_INFO_INTEGRATED,
152 trident->irq, 0, &trident->rmidi)) < 0) { 153 trident->irq, 0, &trident->rmidi)) < 0) {
153 snd_card_free(card); 154 snd_card_free(card);
154 return err; 155 return err;
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 52178b8ad49d..d99ed7237750 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -306,6 +306,8 @@ void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice)
306 outl(mask, TRID_REG(trident, reg)); 306 outl(mask, TRID_REG(trident, reg));
307} 307}
308 308
309EXPORT_SYMBOL(snd_trident_start_voice);
310
309/*--------------------------------------------------------------------------- 311/*---------------------------------------------------------------------------
310 void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice) 312 void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice)
311 313
@@ -328,6 +330,8 @@ void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice)
328 outl(mask, TRID_REG(trident, reg)); 330 outl(mask, TRID_REG(trident, reg));
329} 331}
330 332
333EXPORT_SYMBOL(snd_trident_stop_voice);
334
331/*--------------------------------------------------------------------------- 335/*---------------------------------------------------------------------------
332 int snd_trident_allocate_pcm_channel(struct snd_trident *trident) 336 int snd_trident_allocate_pcm_channel(struct snd_trident *trident)
333 337
@@ -502,6 +506,8 @@ void snd_trident_write_voice_regs(struct snd_trident * trident,
502#endif 506#endif
503} 507}
504 508
509EXPORT_SYMBOL(snd_trident_write_voice_regs);
510
505/*--------------------------------------------------------------------------- 511/*---------------------------------------------------------------------------
506 snd_trident_write_cso_reg 512 snd_trident_write_cso_reg
507 513
@@ -3332,7 +3338,7 @@ static void __devinit snd_trident_proc_init(struct snd_trident * trident)
3332 if (trident->device == TRIDENT_DEVICE_ID_SI7018) 3338 if (trident->device == TRIDENT_DEVICE_ID_SI7018)
3333 s = "sis7018"; 3339 s = "sis7018";
3334 if (! snd_card_proc_new(trident->card, s, &entry)) 3340 if (! snd_card_proc_new(trident->card, s, &entry))
3335 snd_info_set_text_ops(entry, trident, 1024, snd_trident_proc_read); 3341 snd_info_set_text_ops(entry, trident, snd_trident_proc_read);
3336} 3342}
3337 3343
3338static int snd_trident_dev_free(struct snd_device *device) 3344static int snd_trident_dev_free(struct snd_device *device)
@@ -3884,6 +3890,8 @@ struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident,
3884 return NULL; 3890 return NULL;
3885} 3891}
3886 3892
3893EXPORT_SYMBOL(snd_trident_alloc_voice);
3894
3887void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice) 3895void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice)
3888{ 3896{
3889 unsigned long flags; 3897 unsigned long flags;
@@ -3912,6 +3920,8 @@ void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voi
3912 private_free(voice); 3920 private_free(voice);
3913} 3921}
3914 3922
3923EXPORT_SYMBOL(snd_trident_free_voice);
3924
3915static void snd_trident_clear_voices(struct snd_trident * trident, unsigned short v_min, unsigned short v_max) 3925static void snd_trident_clear_voices(struct snd_trident * trident, unsigned short v_min, unsigned short v_max)
3916{ 3926{
3917 unsigned int i, val, mask[2] = { 0, 0 }; 3927 unsigned int i, val, mask[2] = { 0, 0 };
@@ -3993,13 +4003,3 @@ int snd_trident_resume(struct pci_dev *pci)
3993 return 0; 4003 return 0;
3994} 4004}
3995#endif /* CONFIG_PM */ 4005#endif /* CONFIG_PM */
3996
3997EXPORT_SYMBOL(snd_trident_alloc_voice);
3998EXPORT_SYMBOL(snd_trident_free_voice);
3999EXPORT_SYMBOL(snd_trident_start_voice);
4000EXPORT_SYMBOL(snd_trident_stop_voice);
4001EXPORT_SYMBOL(snd_trident_write_voice_regs);
4002/* trident_memory.c symbols */
4003EXPORT_SYMBOL(snd_trident_synth_alloc);
4004EXPORT_SYMBOL(snd_trident_synth_free);
4005EXPORT_SYMBOL(snd_trident_synth_copy_from_user);
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index 46c6982c9e88..aff3f874131c 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -349,6 +349,7 @@ snd_trident_synth_alloc(struct snd_trident *hw, unsigned int size)
349 return blk; 349 return blk;
350} 350}
351 351
352EXPORT_SYMBOL(snd_trident_synth_alloc);
352 353
353/* 354/*
354 * free a synth sample area 355 * free a synth sample area
@@ -365,6 +366,7 @@ snd_trident_synth_free(struct snd_trident *hw, struct snd_util_memblk *blk)
365 return 0; 366 return 0;
366} 367}
367 368
369EXPORT_SYMBOL(snd_trident_synth_free);
368 370
369/* 371/*
370 * reset TLB entry and free kernel page 372 * reset TLB entry and free kernel page
@@ -486,3 +488,4 @@ int snd_trident_synth_copy_from_user(struct snd_trident *trident,
486 return 0; 488 return 0;
487} 489}
488 490
491EXPORT_SYMBOL(snd_trident_synth_copy_from_user);
diff --git a/sound/pci/trident/trident_synth.c b/sound/pci/trident/trident_synth.c
index cc7af8bc55a0..9b7dee84743b 100644
--- a/sound/pci/trident/trident_synth.c
+++ b/sound/pci/trident/trident_synth.c
@@ -914,7 +914,9 @@ static int snd_trident_synth_create_port(struct snd_trident * trident, int idx)
914 &callbacks, 914 &callbacks,
915 SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE, 915 SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
916 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE | 916 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
917 SNDRV_SEQ_PORT_TYPE_SYNTH, 917 SNDRV_SEQ_PORT_TYPE_SYNTH |
918 SNDRV_SEQ_PORT_TYPE_HARDWARE |
919 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
918 16, 0, 920 16, 0,
919 name); 921 name);
920 if (p->chset->port < 0) { 922 if (p->chset->port < 0) {
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 39daf62d2bad..2527bbd958c5 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1775,6 +1775,12 @@ static struct ac97_quirk ac97_quirks[] = {
1775 .name = "Targa Traveller 811", 1775 .name = "Targa Traveller 811",
1776 .type = AC97_TUNE_HP_ONLY, 1776 .type = AC97_TUNE_HP_ONLY,
1777 }, 1777 },
1778 {
1779 .subvendor = 0x161f,
1780 .subdevice = 0x2032,
1781 .name = "m680x",
1782 .type = AC97_TUNE_HP_ONLY, /* http://launchpad.net/bugs/38546 */
1783 },
1778 { } /* terminator */ 1784 { } /* terminator */
1779}; 1785};
1780 1786
@@ -1973,7 +1979,7 @@ static int __devinit snd_via686_init_misc(struct via82xx *chip)
1973 pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg); 1979 pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
1974 if (chip->mpu_res) { 1980 if (chip->mpu_res) {
1975 if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A, 1981 if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A,
1976 mpu_port, 1, 1982 mpu_port, MPU401_INFO_INTEGRATED,
1977 chip->irq, 0, &chip->rmidi) < 0) { 1983 chip->irq, 0, &chip->rmidi) < 0) {
1978 printk(KERN_WARNING "unable to initialize MPU-401" 1984 printk(KERN_WARNING "unable to initialize MPU-401"
1979 " at 0x%lx, skipping\n", mpu_port); 1985 " at 0x%lx, skipping\n", mpu_port);
@@ -2015,7 +2021,7 @@ static void __devinit snd_via82xx_proc_init(struct via82xx *chip)
2015 struct snd_info_entry *entry; 2021 struct snd_info_entry *entry;
2016 2022
2017 if (! snd_card_proc_new(chip->card, "via82xx", &entry)) 2023 if (! snd_card_proc_new(chip->card, "via82xx", &entry))
2018 snd_info_set_text_ops(entry, chip, 1024, snd_via82xx_proc_read); 2024 snd_info_set_text_ops(entry, chip, snd_via82xx_proc_read);
2019} 2025}
2020 2026
2021/* 2027/*
@@ -2365,7 +2371,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci, int revision)
2365 { .subvendor = 0x1462, .subdevice = 0x0470, .action = VIA_DXS_SRC }, /* MSI KT880 Delta-FSR */ 2371 { .subvendor = 0x1462, .subdevice = 0x0470, .action = VIA_DXS_SRC }, /* MSI KT880 Delta-FSR */
2366 { .subvendor = 0x1462, .subdevice = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */ 2372 { .subvendor = 0x1462, .subdevice = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */
2367 { .subvendor = 0x1462, .subdevice = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */ 2373 { .subvendor = 0x1462, .subdevice = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */
2368 { .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */ 2374 { .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_SRC }, /* MSI K8T Neo2-FI */
2369 { .subvendor = 0x1462, .subdevice = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */ 2375 { .subvendor = 0x1462, .subdevice = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */
2370 { .subvendor = 0x1462, .subdevice = 0x7142, .action = VIA_DXS_ENABLE }, /* MSI K8MM-V */ 2376 { .subvendor = 0x1462, .subdevice = 0x7142, .action = VIA_DXS_ENABLE }, /* MSI K8MM-V */
2371 { .subvendor = 0x1462, .subdevice = 0xb012, .action = VIA_DXS_SRC }, /* P4M800/VIA8237R */ 2377 { .subvendor = 0x1462, .subdevice = 0xb012, .action = VIA_DXS_SRC }, /* P4M800/VIA8237R */
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index ef97e50cd6c2..577a2b03759f 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -929,7 +929,7 @@ static void __devinit snd_via82xx_proc_init(struct via82xx_modem *chip)
929 struct snd_info_entry *entry; 929 struct snd_info_entry *entry;
930 930
931 if (! snd_card_proc_new(chip->card, "via82xx", &entry)) 931 if (! snd_card_proc_new(chip->card, "via82xx", &entry))
932 snd_info_set_text_ops(entry, chip, 1024, snd_via82xx_proc_read); 932 snd_info_set_text_ops(entry, chip, snd_via82xx_proc_read);
933} 933}
934 934
935/* 935/*
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 65ebf5f1933a..26aa775b7b69 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -308,7 +308,8 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
308 } 308 }
309 if (chip->mpu_res) { 309 if (chip->mpu_res) {
310 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI, 310 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,
311 mpu_port[dev], 1, 311 mpu_port[dev],
312 MPU401_INFO_INTEGRATED,
312 pci->irq, 0, &chip->rawmidi)) < 0) { 313 pci->irq, 0, &chip->rawmidi)) < 0) {
313 printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]); 314 printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]);
314 legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */ 315 legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 8ac5ab50b5c7..f894752523bb 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -1919,7 +1919,7 @@ static int __devinit snd_ymfpci_proc_init(struct snd_card *card, struct snd_ymfp
1919 struct snd_info_entry *entry; 1919 struct snd_info_entry *entry;
1920 1920
1921 if (! snd_card_proc_new(card, "ymfpci", &entry)) 1921 if (! snd_card_proc_new(card, "ymfpci", &entry))
1922 snd_info_set_text_ops(entry, chip, 1024, snd_ymfpci_proc_read); 1922 snd_info_set_text_ops(entry, chip, snd_ymfpci_proc_read);
1923 return 0; 1923 return 0;
1924} 1924}
1925 1925
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
index bd0d70ff3019..1dfe29b863d3 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
@@ -144,7 +144,7 @@ static void pdacf_proc_init(struct snd_pdacf *chip)
144 struct snd_info_entry *entry; 144 struct snd_info_entry *entry;
145 145
146 if (! snd_card_proc_new(chip->card, "pdaudiocf", &entry)) 146 if (! snd_card_proc_new(chip->card, "pdaudiocf", &entry))
147 snd_info_set_text_ops(entry, chip, 1024, pdacf_proc_read); 147 snd_info_set_text_ops(entry, chip, pdacf_proc_read);
148} 148}
149 149
150struct snd_pdacf *snd_pdacf_create(struct snd_card *card) 150struct snd_pdacf *snd_pdacf_create(struct snd_card *card)
diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c
index 7f82f619f9f4..1ee0918c3b9f 100644
--- a/sound/pcmcia/vx/vxp_ops.c
+++ b/sound/pcmcia/vx/vxp_ops.c
@@ -202,7 +202,7 @@ static int vxp_load_xilinx_binary(struct vx_core *_chip, const struct firmware *
202 c |= (int)vx_inb(chip, RXM) << 8; 202 c |= (int)vx_inb(chip, RXM) << 8;
203 c |= vx_inb(chip, RXL); 203 c |= vx_inb(chip, RXL);
204 204
205 snd_printdd(KERN_DEBUG "xilinx: dsp size received 0x%x, orig 0x%x\n", c, fw->size); 205 snd_printdd(KERN_DEBUG "xilinx: dsp size received 0x%x, orig 0x%Zx\n", c, fw->size);
206 206
207 vx_outb(chip, ICR, ICR_HF0); 207 vx_outb(chip, ICR, ICR_HF0);
208 208
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 7e0cda2b6ef9..cafe6640cc1a 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -261,7 +261,7 @@ static int vxpocket_config(struct pcmcia_device *link)
261 261
262 link->dev_node = &vxp->node; 262 link->dev_node = &vxp->node;
263 kfree(parse); 263 kfree(parse);
264 return 9; 264 return 0;
265 265
266cs_failed: 266cs_failed:
267 cs_error(link, last_fn, last_ret); 267 cs_error(link, last_fn, last_ret);
diff --git a/sound/ppc/Makefile b/sound/ppc/Makefile
index d6ba9959097b..4d95c652c8ca 100644
--- a/sound/ppc/Makefile
+++ b/sound/ppc/Makefile
@@ -3,7 +3,7 @@
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> 3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4# 4#
5 5
6snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o toonie.o keywest.o beep.o 6snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o
7 7
8# Toplevel Module Dependency 8# Toplevel Module Dependency
9obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o 9obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index f0794ef9d1ac..b678814975c9 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -867,8 +867,6 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
867 unsigned int *prop, l; 867 unsigned int *prop, l;
868 struct macio_chip* macio; 868 struct macio_chip* macio;
869 869
870 u32 layout_id = 0;
871
872 if (!machine_is(powermac)) 870 if (!machine_is(powermac))
873 return -ENODEV; 871 return -ENODEV;
874 872
@@ -929,8 +927,14 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
929 if (prop && *prop < 16) 927 if (prop && *prop < 16)
930 chip->subframe = *prop; 928 chip->subframe = *prop;
931 prop = (unsigned int *) get_property(sound, "layout-id", NULL); 929 prop = (unsigned int *) get_property(sound, "layout-id", NULL);
932 if (prop) 930 if (prop) {
933 layout_id = *prop; 931 /* partly deprecate snd-powermac, for those machines
932 * that have a layout-id property for now */
933 printk(KERN_INFO "snd-powermac no longer handles any "
934 "machines with a layout-id property "
935 "in the device-tree, use snd-aoa.\n");
936 return -ENODEV;
937 }
934 /* This should be verified on older screamers */ 938 /* This should be verified on older screamers */
935 if (device_is_compatible(sound, "screamer")) { 939 if (device_is_compatible(sound, "screamer")) {
936 chip->model = PMAC_SCREAMER; 940 chip->model = PMAC_SCREAMER;
@@ -963,38 +967,6 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
963 chip->freq_table = tumbler_freqs; 967 chip->freq_table = tumbler_freqs;
964 chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ 968 chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
965 } 969 }
966 if (device_is_compatible(sound, "AOAKeylargo") ||
967 device_is_compatible(sound, "AOAbase") ||
968 device_is_compatible(sound, "AOAK2")) {
969 /* For now, only support very basic TAS3004 based machines with
970 * single frequency until proper i2s control is implemented
971 */
972 switch(layout_id) {
973 case 0x24:
974 case 0x29:
975 case 0x33:
976 case 0x46:
977 case 0x48:
978 case 0x50:
979 case 0x5c:
980 chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
981 chip->model = PMAC_SNAPPER;
982 chip->can_byte_swap = 0; /* FIXME: check this */
983 chip->control_mask = MASK_IEPC | 0x11;/* disable IEE */
984 break;
985 case 0x3a:
986 chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
987 chip->model = PMAC_TOONIE;
988 chip->can_byte_swap = 0; /* FIXME: check this */
989 chip->control_mask = MASK_IEPC | 0x11;/* disable IEE */
990 break;
991 default:
992 printk(KERN_ERR "snd: Unknown layout ID 0x%x\n",
993 layout_id);
994 return -ENODEV;
995
996 }
997 }
998 prop = (unsigned int *)get_property(sound, "device-id", NULL); 970 prop = (unsigned int *)get_property(sound, "device-id", NULL);
999 if (prop) 971 if (prop)
1000 chip->device_id = *prop; 972 chip->device_id = *prop;
diff --git a/sound/ppc/pmac.h b/sound/ppc/pmac.h
index 3a9bd4dbb9a6..8394e66ceb00 100644
--- a/sound/ppc/pmac.h
+++ b/sound/ppc/pmac.h
@@ -85,7 +85,7 @@ struct pmac_stream {
85 85
86enum snd_pmac_model { 86enum snd_pmac_model {
87 PMAC_AWACS, PMAC_SCREAMER, PMAC_BURGUNDY, PMAC_DACA, PMAC_TUMBLER, 87 PMAC_AWACS, PMAC_SCREAMER, PMAC_BURGUNDY, PMAC_DACA, PMAC_TUMBLER,
88 PMAC_SNAPPER, PMAC_TOONIE 88 PMAC_SNAPPER
89}; 89};
90 90
91struct snd_pmac { 91struct snd_pmac {
@@ -188,7 +188,6 @@ int snd_pmac_burgundy_init(struct snd_pmac *chip);
188int snd_pmac_daca_init(struct snd_pmac *chip); 188int snd_pmac_daca_init(struct snd_pmac *chip);
189int snd_pmac_tumbler_init(struct snd_pmac *chip); 189int snd_pmac_tumbler_init(struct snd_pmac *chip);
190int snd_pmac_tumbler_post_init(void); 190int snd_pmac_tumbler_post_init(void);
191int snd_pmac_toonie_init(struct snd_pmac *chip);
192 191
193/* i2c functions */ 192/* i2c functions */
194struct pmac_keywest { 193struct pmac_keywest {
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index f4902a219e50..fa9a44ab487e 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -94,13 +94,6 @@ static int __init snd_pmac_probe(struct platform_device *devptr)
94 if ( snd_pmac_tumbler_init(chip) < 0 || snd_pmac_tumbler_post_init() < 0) 94 if ( snd_pmac_tumbler_init(chip) < 0 || snd_pmac_tumbler_post_init() < 0)
95 goto __error; 95 goto __error;
96 break; 96 break;
97 case PMAC_TOONIE:
98 strcpy(card->driver, "PMac Toonie");
99 strcpy(card->shortname, "PowerMac Toonie");
100 strcpy(card->longname, card->shortname);
101 if ((err = snd_pmac_toonie_init(chip)) < 0)
102 goto __error;
103 break;
104 case PMAC_AWACS: 97 case PMAC_AWACS:
105 case PMAC_SCREAMER: 98 case PMAC_SCREAMER:
106 name_ext = chip->model == PMAC_SCREAMER ? "Screamer" : "AWACS"; 99 name_ext = chip->model == PMAC_SCREAMER ? "Screamer" : "AWACS";
@@ -188,11 +181,15 @@ static int __init alsa_card_pmac_init(void)
188 if ((err = platform_driver_register(&snd_pmac_driver)) < 0) 181 if ((err = platform_driver_register(&snd_pmac_driver)) < 0)
189 return err; 182 return err;
190 device = platform_device_register_simple(SND_PMAC_DRIVER, -1, NULL, 0); 183 device = platform_device_register_simple(SND_PMAC_DRIVER, -1, NULL, 0);
191 if (IS_ERR(device)) { 184 if (!IS_ERR(device)) {
192 platform_driver_unregister(&snd_pmac_driver); 185 if (platform_get_drvdata(device))
193 return PTR_ERR(device); 186 return 0;
194 } 187 platform_device_unregister(device);
195 return 0; 188 err = -ENODEV;
189 } else
190 err = PTR_ERR(device);
191 platform_driver_unregister(&snd_pmac_driver);
192 return err;
196 193
197} 194}
198 195
diff --git a/sound/ppc/toonie.c b/sound/ppc/toonie.c
index 1ac7c8552f50..e69de29bb2d1 100644
--- a/sound/ppc/toonie.c
+++ b/sound/ppc/toonie.c
@@ -1,378 +0,0 @@
1/*
2 * Mac Mini "toonie" mixer control
3 *
4 * Copyright (c) 2005 by Benjamin Herrenschmidt <benh@kernel.crashing.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <sound/driver.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/i2c.h>
25#include <linux/kmod.h>
26#include <linux/slab.h>
27#include <linux/interrupt.h>
28#include <sound/core.h>
29#include <asm/io.h>
30#include <asm/irq.h>
31#include <asm/machdep.h>
32#include <asm/pmac_feature.h>
33#include "pmac.h"
34
35#undef DEBUG
36
37#ifdef DEBUG
38#define DBG(fmt...) printk(fmt)
39#else
40#define DBG(fmt...)
41#endif
42
43struct pmac_gpio {
44 unsigned int addr;
45 u8 active_val;
46 u8 inactive_val;
47 u8 active_state;
48};
49
50struct pmac_toonie
51{
52 struct pmac_gpio hp_detect_gpio;
53 struct pmac_gpio hp_mute_gpio;
54 struct pmac_gpio amp_mute_gpio;
55 int hp_detect_irq;
56 int auto_mute_notify;
57 struct work_struct detect_work;
58};
59
60
61/*
62 * gpio access
63 */
64#define do_gpio_write(gp, val) \
65 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, (gp)->addr, val)
66#define do_gpio_read(gp) \
67 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, (gp)->addr, 0)
68#define tumbler_gpio_free(gp) /* NOP */
69
70static void write_audio_gpio(struct pmac_gpio *gp, int active)
71{
72 if (! gp->addr)
73 return;
74 active = active ? gp->active_val : gp->inactive_val;
75 do_gpio_write(gp, active);
76 DBG("(I) gpio %x write %d\n", gp->addr, active);
77}
78
79static int check_audio_gpio(struct pmac_gpio *gp)
80{
81 int ret;
82
83 if (! gp->addr)
84 return 0;
85
86 ret = do_gpio_read(gp);
87
88 return (ret & 0xd) == (gp->active_val & 0xd);
89}
90
91static int read_audio_gpio(struct pmac_gpio *gp)
92{
93 int ret;
94 if (! gp->addr)
95 return 0;
96 ret = ((do_gpio_read(gp) & 0x02) !=0);
97 return ret == gp->active_state;
98}
99
100
101enum { TOONIE_MUTE_HP, TOONIE_MUTE_AMP };
102
103static int toonie_get_mute_switch(struct snd_kcontrol *kcontrol,
104 struct snd_ctl_elem_value *ucontrol)
105{
106 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
107 struct pmac_toonie *mix = chip->mixer_data;
108 struct pmac_gpio *gp;
109
110 if (mix == NULL)
111 return -ENODEV;
112 switch(kcontrol->private_value) {
113 case TOONIE_MUTE_HP:
114 gp = &mix->hp_mute_gpio;
115 break;
116 case TOONIE_MUTE_AMP:
117 gp = &mix->amp_mute_gpio;
118 break;
119 default:
120 return -EINVAL;
121 }
122 ucontrol->value.integer.value[0] = !check_audio_gpio(gp);
123 return 0;
124}
125
126static int toonie_put_mute_switch(struct snd_kcontrol *kcontrol,
127 struct snd_ctl_elem_value *ucontrol)
128{
129 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
130 struct pmac_toonie *mix = chip->mixer_data;
131 struct pmac_gpio *gp;
132 int val;
133
134 if (chip->update_automute && chip->auto_mute)
135 return 0; /* don't touch in the auto-mute mode */
136
137 if (mix == NULL)
138 return -ENODEV;
139
140 switch(kcontrol->private_value) {
141 case TOONIE_MUTE_HP:
142 gp = &mix->hp_mute_gpio;
143 break;
144 case TOONIE_MUTE_AMP:
145 gp = &mix->amp_mute_gpio;
146 break;
147 default:
148 return -EINVAL;
149 }
150 val = ! check_audio_gpio(gp);
151 if (val != ucontrol->value.integer.value[0]) {
152 write_audio_gpio(gp, ! ucontrol->value.integer.value[0]);
153 return 1;
154 }
155 return 0;
156}
157
158static struct snd_kcontrol_new toonie_hp_sw __initdata = {
159 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
160 .name = "Headphone Playback Switch",
161 .info = snd_pmac_boolean_mono_info,
162 .get = toonie_get_mute_switch,
163 .put = toonie_put_mute_switch,
164 .private_value = TOONIE_MUTE_HP,
165};
166static struct snd_kcontrol_new toonie_speaker_sw __initdata = {
167 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
168 .name = "PC Speaker Playback Switch",
169 .info = snd_pmac_boolean_mono_info,
170 .get = toonie_get_mute_switch,
171 .put = toonie_put_mute_switch,
172 .private_value = TOONIE_MUTE_AMP,
173};
174
175/*
176 * auto-mute stuffs
177 */
178static int toonie_detect_headphone(struct snd_pmac *chip)
179{
180 struct pmac_toonie *mix = chip->mixer_data;
181 int detect = 0;
182
183 if (mix->hp_detect_gpio.addr)
184 detect |= read_audio_gpio(&mix->hp_detect_gpio);
185 return detect;
186}
187
188static void toonie_check_mute(struct snd_pmac *chip, struct pmac_gpio *gp, int val,
189 int do_notify, struct snd_kcontrol *sw)
190{
191 if (check_audio_gpio(gp) != val) {
192 write_audio_gpio(gp, val);
193 if (do_notify)
194 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
195 &sw->id);
196 }
197}
198
199static void toonie_detect_handler(void *self)
200{
201 struct snd_pmac *chip = (struct snd_pmac *) self;
202 struct pmac_toonie *mix;
203 int headphone;
204
205 if (!chip)
206 return;
207
208 mix = chip->mixer_data;
209 snd_assert(mix, return);
210
211 headphone = toonie_detect_headphone(chip);
212
213 DBG("headphone: %d, lineout: %d\n", headphone, lineout);
214
215 if (headphone) {
216 /* unmute headphone/lineout & mute speaker */
217 toonie_check_mute(chip, &mix->hp_mute_gpio, 0,
218 mix->auto_mute_notify, chip->master_sw_ctl);
219 toonie_check_mute(chip, &mix->amp_mute_gpio, 1,
220 mix->auto_mute_notify, chip->speaker_sw_ctl);
221 } else {
222 /* unmute speaker, mute others */
223 toonie_check_mute(chip, &mix->amp_mute_gpio, 0,
224 mix->auto_mute_notify, chip->speaker_sw_ctl);
225 toonie_check_mute(chip, &mix->hp_mute_gpio, 1,
226 mix->auto_mute_notify, chip->master_sw_ctl);
227 }
228 if (mix->auto_mute_notify) {
229 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
230 &chip->hp_detect_ctl->id);
231 }
232}
233
234static void toonie_update_automute(struct snd_pmac *chip, int do_notify)
235{
236 if (chip->auto_mute) {
237 struct pmac_toonie *mix;
238 mix = chip->mixer_data;
239 snd_assert(mix, return);
240 mix->auto_mute_notify = do_notify;
241 schedule_work(&mix->detect_work);
242 }
243}
244
245/* interrupt - headphone plug changed */
246static irqreturn_t toonie_hp_intr(int irq, void *devid, struct pt_regs *regs)
247{
248 struct snd_pmac *chip = devid;
249
250 if (chip->update_automute && chip->initialized) {
251 chip->update_automute(chip, 1);
252 return IRQ_HANDLED;
253 }
254 return IRQ_NONE;
255}
256
257/* look for audio gpio device */
258static int find_audio_gpio(const char *name, const char *platform,
259 struct pmac_gpio *gp)
260{
261 struct device_node *np;
262 u32 *base, addr;
263
264 if (! (np = find_devices("gpio")))
265 return -ENODEV;
266
267 for (np = np->child; np; np = np->sibling) {
268 char *property = get_property(np, "audio-gpio", NULL);
269 if (property && strcmp(property, name) == 0)
270 break;
271 if (device_is_compatible(np, name))
272 break;
273 }
274 if (np == NULL)
275 return -ENODEV;
276
277 base = (u32 *)get_property(np, "AAPL,address", NULL);
278 if (! base) {
279 base = (u32 *)get_property(np, "reg", NULL);
280 if (!base) {
281 DBG("(E) cannot find address for device %s !\n", name);
282 return -ENODEV;
283 }
284 addr = *base;
285 if (addr < 0x50)
286 addr += 0x50;
287 } else
288 addr = *base;
289
290 gp->addr = addr & 0x0000ffff;
291
292 /* Try to find the active state, default to 0 ! */
293 base = (u32 *)get_property(np, "audio-gpio-active-state", NULL);
294 if (base) {
295 gp->active_state = *base;
296 gp->active_val = (*base) ? 0x5 : 0x4;
297 gp->inactive_val = (*base) ? 0x4 : 0x5;
298 } else {
299 u32 *prop = NULL;
300 gp->active_state = 0;
301 gp->active_val = 0x4;
302 gp->inactive_val = 0x5;
303 /* Here are some crude hacks to extract the GPIO polarity and
304 * open collector informations out of the do-platform script
305 * as we don't yet have an interpreter for these things
306 */
307 if (platform)
308 prop = (u32 *)get_property(np, platform, NULL);
309 if (prop) {
310 if (prop[3] == 0x9 && prop[4] == 0x9) {
311 gp->active_val = 0xd;
312 gp->inactive_val = 0xc;
313 }
314 if (prop[3] == 0x1 && prop[4] == 0x1) {
315 gp->active_val = 0x5;
316 gp->inactive_val = 0x4;
317 }
318 }
319 }
320
321 DBG("(I) GPIO device %s found, offset: %x, active state: %d !\n",
322 name, gp->addr, gp->active_state);
323
324 return (np->n_intrs > 0) ? np->intrs[0].line : 0;
325}
326
327static void toonie_cleanup(struct snd_pmac *chip)
328{
329 struct pmac_toonie *mix = chip->mixer_data;
330 if (! mix)
331 return;
332 if (mix->hp_detect_irq >= 0)
333 free_irq(mix->hp_detect_irq, chip);
334 kfree(mix);
335 chip->mixer_data = NULL;
336}
337
338int __init snd_pmac_toonie_init(struct snd_pmac *chip)
339{
340 struct pmac_toonie *mix;
341
342 mix = kmalloc(sizeof(*mix), GFP_KERNEL);
343 if (! mix)
344 return -ENOMEM;
345
346 chip->mixer_data = mix;
347 chip->mixer_free = toonie_cleanup;
348
349 find_audio_gpio("headphone-mute", NULL, &mix->hp_mute_gpio);
350 find_audio_gpio("amp-mute", NULL, &mix->amp_mute_gpio);
351 mix->hp_detect_irq = find_audio_gpio("headphone-detect",
352 NULL, &mix->hp_detect_gpio);
353
354 strcpy(chip->card->mixername, "PowerMac Toonie");
355
356 chip->master_sw_ctl = snd_ctl_new1(&toonie_hp_sw, chip);
357 snd_ctl_add(chip->card, chip->master_sw_ctl);
358
359 chip->speaker_sw_ctl = snd_ctl_new1(&toonie_speaker_sw, chip);
360 snd_ctl_add(chip->card, chip->speaker_sw_ctl);
361
362 INIT_WORK(&mix->detect_work, toonie_detect_handler, (void *)chip);
363
364 if (mix->hp_detect_irq >= 0) {
365 snd_pmac_add_automute(chip);
366
367 chip->detect_headphone = toonie_detect_headphone;
368 chip->update_automute = toonie_update_automute;
369 toonie_update_automute(chip, 0);
370
371 if (request_irq(mix->hp_detect_irq, toonie_hp_intr, 0,
372 "Sound Headphone Detection", chip) < 0)
373 mix->hp_detect_irq = -1;
374 }
375
376 return 0;
377}
378
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index e622d08215c9..5eecdd09a79d 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -92,7 +92,7 @@ MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard.");
92#define D_USR (1<<4) 92#define D_USR (1<<4)
93#define D_DESC (1<<5) 93#define D_DESC (1<<5)
94 94
95static int dbri_debug = 0; 95static int dbri_debug;
96module_param(dbri_debug, int, 0644); 96module_param(dbri_debug, int, 0644);
97MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard."); 97MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard.");
98 98
@@ -593,7 +593,7 @@ struct snd_dbri {
593/* Return a pointer to dbri_streaminfo */ 593/* Return a pointer to dbri_streaminfo */
594#define DBRI_STREAM(dbri, substream) &dbri->stream_info[DBRI_STREAMNO(substream)] 594#define DBRI_STREAM(dbri, substream) &dbri->stream_info[DBRI_STREAMNO(substream)]
595 595
596static struct snd_dbri *dbri_list = NULL; /* All DBRI devices */ 596static struct snd_dbri *dbri_list; /* All DBRI devices */
597 597
598/* 598/*
599 * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr. 599 * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr.
@@ -2521,11 +2521,11 @@ void snd_dbri_proc(struct snd_dbri * dbri)
2521 struct snd_info_entry *entry; 2521 struct snd_info_entry *entry;
2522 2522
2523 if (! snd_card_proc_new(dbri->card, "regs", &entry)) 2523 if (! snd_card_proc_new(dbri->card, "regs", &entry))
2524 snd_info_set_text_ops(entry, dbri, 1024, dbri_regs_read); 2524 snd_info_set_text_ops(entry, dbri, dbri_regs_read);
2525 2525
2526#ifdef DBRI_DEBUG 2526#ifdef DBRI_DEBUG
2527 if (! snd_card_proc_new(dbri->card, "debug", &entry)) { 2527 if (! snd_card_proc_new(dbri->card, "debug", &entry)) {
2528 snd_info_set_text_ops(entry, dbri, 4096, dbri_debug_read); 2528 snd_info_set_text_ops(entry, dbri, dbri_debug_read);
2529 entry->mode = S_IFREG | S_IRUGO; /* Readable only. */ 2529 entry->mode = S_IFREG | S_IRUGO; /* Readable only. */
2530 } 2530 }
2531#endif 2531#endif
diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c
index fc733bbf4487..573e3701c14f 100644
--- a/sound/synth/emux/emux.c
+++ b/sound/synth/emux/emux.c
@@ -63,6 +63,7 @@ int snd_emux_new(struct snd_emux **remu)
63 return 0; 63 return 0;
64} 64}
65 65
66EXPORT_SYMBOL(snd_emux_new);
66 67
67/* 68/*
68 */ 69 */
@@ -136,6 +137,7 @@ int snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, ch
136 return 0; 137 return 0;
137} 138}
138 139
140EXPORT_SYMBOL(snd_emux_register);
139 141
140/* 142/*
141 */ 143 */
@@ -171,18 +173,8 @@ int snd_emux_free(struct snd_emux *emu)
171 return 0; 173 return 0;
172} 174}
173 175
174
175EXPORT_SYMBOL(snd_emux_new);
176EXPORT_SYMBOL(snd_emux_register);
177EXPORT_SYMBOL(snd_emux_free); 176EXPORT_SYMBOL(snd_emux_free);
178 177
179EXPORT_SYMBOL(snd_emux_terminate_all);
180EXPORT_SYMBOL(snd_emux_lock_voice);
181EXPORT_SYMBOL(snd_emux_unlock_voice);
182
183/* soundfont.c */
184EXPORT_SYMBOL(snd_sf_linear_to_log);
185
186 178
187/* 179/*
188 * INIT part 180 * INIT part
diff --git a/sound/synth/emux/emux_proc.c b/sound/synth/emux/emux_proc.c
index 1ba68ce30279..58b9601f3ad0 100644
--- a/sound/synth/emux/emux_proc.c
+++ b/sound/synth/emux/emux_proc.c
@@ -119,7 +119,6 @@ void snd_emux_proc_init(struct snd_emux *emu, struct snd_card *card, int device)
119 119
120 entry->content = SNDRV_INFO_CONTENT_TEXT; 120 entry->content = SNDRV_INFO_CONTENT_TEXT;
121 entry->private_data = emu; 121 entry->private_data = emu;
122 entry->c.text.read_size = 1024;
123 entry->c.text.read = snd_emux_proc_info_read; 122 entry->c.text.read = snd_emux_proc_info_read;
124 if (snd_info_register(entry) < 0) 123 if (snd_info_register(entry) < 0)
125 snd_info_free_entry(entry); 124 snd_info_free_entry(entry);
diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c
index 8f00f07701c4..d176cc01742d 100644
--- a/sound/synth/emux/emux_seq.c
+++ b/sound/synth/emux/emux_seq.c
@@ -55,7 +55,8 @@ static struct snd_midi_op emux_ops = {
55 SNDRV_SEQ_PORT_TYPE_MIDI_GM |\ 55 SNDRV_SEQ_PORT_TYPE_MIDI_GM |\
56 SNDRV_SEQ_PORT_TYPE_MIDI_GS |\ 56 SNDRV_SEQ_PORT_TYPE_MIDI_GS |\
57 SNDRV_SEQ_PORT_TYPE_MIDI_XG |\ 57 SNDRV_SEQ_PORT_TYPE_MIDI_XG |\
58 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE) 58 SNDRV_SEQ_PORT_TYPE_HARDWARE |\
59 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER)
59 60
60/* 61/*
61 * Initialise the EMUX Synth by creating a client and registering 62 * Initialise the EMUX Synth by creating a client and registering
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c
index 24705d15ebd8..3733118d39bb 100644
--- a/sound/synth/emux/emux_synth.c
+++ b/sound/synth/emux/emux_synth.c
@@ -434,6 +434,7 @@ snd_emux_terminate_all(struct snd_emux *emu)
434 spin_unlock_irqrestore(&emu->voice_lock, flags); 434 spin_unlock_irqrestore(&emu->voice_lock, flags);
435} 435}
436 436
437EXPORT_SYMBOL(snd_emux_terminate_all);
437 438
438/* 439/*
439 * Terminate all voices associated with the given port 440 * Terminate all voices associated with the given port
@@ -951,6 +952,8 @@ void snd_emux_lock_voice(struct snd_emux *emu, int voice)
951 spin_unlock_irqrestore(&emu->voice_lock, flags); 952 spin_unlock_irqrestore(&emu->voice_lock, flags);
952} 953}
953 954
955EXPORT_SYMBOL(snd_emux_lock_voice);
956
954/* 957/*
955 */ 958 */
956void snd_emux_unlock_voice(struct snd_emux *emu, int voice) 959void snd_emux_unlock_voice(struct snd_emux *emu, int voice)
@@ -965,3 +968,5 @@ void snd_emux_unlock_voice(struct snd_emux *emu, int voice)
965 voice, emu->voices[voice].state); 968 voice, emu->voices[voice].state);
966 spin_unlock_irqrestore(&emu->voice_lock, flags); 969 spin_unlock_irqrestore(&emu->voice_lock, flags);
967} 970}
971
972EXPORT_SYMBOL(snd_emux_unlock_voice);
diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c
index 32c27162dfb6..455e535933ec 100644
--- a/sound/synth/emux/soundfont.c
+++ b/sound/synth/emux/soundfont.c
@@ -195,7 +195,7 @@ snd_soundfont_load(struct snd_sf_list *sflist, const void __user *data,
195 break; 195 break;
196 case SNDRV_SFNT_REMOVE_INFO: 196 case SNDRV_SFNT_REMOVE_INFO:
197 /* patch must be opened */ 197 /* patch must be opened */
198 if (sflist->currsf) { 198 if (!sflist->currsf) {
199 snd_printk("soundfont: remove_info: patch not opened\n"); 199 snd_printk("soundfont: remove_info: patch not opened\n");
200 rc = -EINVAL; 200 rc = -EINVAL;
201 } else { 201 } else {
@@ -810,6 +810,9 @@ snd_sf_linear_to_log(unsigned int amount, int offset, int ratio)
810 return v; 810 return v;
811} 811}
812 812
813EXPORT_SYMBOL(snd_sf_linear_to_log);
814
815
813#define OFFSET_MSEC 653117 /* base = 1000 */ 816#define OFFSET_MSEC 653117 /* base = 1000 */
814#define OFFSET_ABSCENT 851781 /* base = 8176 */ 817#define OFFSET_ABSCENT 851781 /* base = 8176 */
815#define OFFSET_SAMPLERATE 1011119 /* base = 44100 */ 818#define OFFSET_SAMPLERATE 1011119 /* base = 44100 */
@@ -1485,4 +1488,3 @@ snd_soundfont_remove_unlocked(struct snd_sf_list *sflist)
1485 unlock_preset(sflist); 1488 unlock_preset(sflist);
1486 return 0; 1489 return 0;
1487} 1490}
1488
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 4e614ac39f21..627de9525a32 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -2138,7 +2138,7 @@ static void proc_pcm_format_add(struct snd_usb_stream *stream)
2138 2138
2139 sprintf(name, "stream%d", stream->pcm_index); 2139 sprintf(name, "stream%d", stream->pcm_index);
2140 if (! snd_card_proc_new(card, name, &entry)) 2140 if (! snd_card_proc_new(card, name, &entry))
2141 snd_info_set_text_ops(entry, stream, 1024, proc_pcm_format_read); 2141 snd_info_set_text_ops(entry, stream, proc_pcm_format_read);
2142} 2142}
2143 2143
2144#else 2144#else
@@ -2627,9 +2627,10 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2627 if (!csep && altsd->bNumEndpoints >= 2) 2627 if (!csep && altsd->bNumEndpoints >= 2)
2628 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); 2628 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
2629 if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) { 2629 if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) {
2630 snd_printk(KERN_ERR "%d:%u:%d : no or invalid class specific endpoint descriptor\n", 2630 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
2631 " class specific endpoint descriptor\n",
2631 dev->devnum, iface_no, altno); 2632 dev->devnum, iface_no, altno);
2632 continue; 2633 csep = NULL;
2633 } 2634 }
2634 2635
2635 fp = kmalloc(sizeof(*fp), GFP_KERNEL); 2636 fp = kmalloc(sizeof(*fp), GFP_KERNEL);
@@ -2648,7 +2649,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2648 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) 2649 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
2649 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) 2650 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
2650 * (fp->maxpacksize & 0x7ff); 2651 * (fp->maxpacksize & 0x7ff);
2651 fp->attributes = csep[3]; 2652 fp->attributes = csep ? csep[3] : 0;
2652 2653
2653 /* some quirks for attributes here */ 2654 /* some quirks for attributes here */
2654 2655
@@ -2980,7 +2981,7 @@ static int create_ua1000_quirk(struct snd_usb_audio *chip,
2980 return -ENXIO; 2981 return -ENXIO;
2981 alts = &iface->altsetting[1]; 2982 alts = &iface->altsetting[1];
2982 altsd = get_iface_desc(alts); 2983 altsd = get_iface_desc(alts);
2983 if (alts->extralen != 11 || alts->extra[1] != CS_AUDIO_INTERFACE || 2984 if (alts->extralen != 11 || alts->extra[1] != USB_DT_CS_INTERFACE ||
2984 altsd->bNumEndpoints != 1) 2985 altsd->bNumEndpoints != 1)
2985 return -ENXIO; 2986 return -ENXIO;
2986 2987
@@ -3197,9 +3198,9 @@ static void snd_usb_audio_create_proc(struct snd_usb_audio *chip)
3197{ 3198{
3198 struct snd_info_entry *entry; 3199 struct snd_info_entry *entry;
3199 if (! snd_card_proc_new(chip->card, "usbbus", &entry)) 3200 if (! snd_card_proc_new(chip->card, "usbbus", &entry))
3200 snd_info_set_text_ops(entry, chip, 1024, proc_audio_usbbus_read); 3201 snd_info_set_text_ops(entry, chip, proc_audio_usbbus_read);
3201 if (! snd_card_proc_new(chip->card, "usbid", &entry)) 3202 if (! snd_card_proc_new(chip->card, "usbid", &entry))
3202 snd_info_set_text_ops(entry, chip, 1024, proc_audio_usbid_read); 3203 snd_info_set_text_ops(entry, chip, proc_audio_usbid_read);
3203} 3204}
3204 3205
3205/* 3206/*
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 88733524d0fb..0f4b2b8541d6 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -30,13 +30,6 @@
30#define USB_SUBCLASS_MIDI_STREAMING 0x03 30#define USB_SUBCLASS_MIDI_STREAMING 0x03
31#define USB_SUBCLASS_VENDOR_SPEC 0xff 31#define USB_SUBCLASS_VENDOR_SPEC 0xff
32 32
33#define CS_AUDIO_UNDEFINED 0x20
34#define CS_AUDIO_DEVICE 0x21
35#define CS_AUDIO_CONFIGURATION 0x22
36#define CS_AUDIO_STRING 0x23
37#define CS_AUDIO_INTERFACE 0x24
38#define CS_AUDIO_ENDPOINT 0x25
39
40#define HEADER 0x01 33#define HEADER 0x01
41#define INPUT_TERMINAL 0x02 34#define INPUT_TERMINAL 0x02
42#define OUTPUT_TERMINAL 0x03 35#define OUTPUT_TERMINAL 0x03
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 2b9d940c8064..5105b6b05748 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -48,6 +48,7 @@
48#include <linux/usb.h> 48#include <linux/usb.h>
49#include <sound/core.h> 49#include <sound/core.h>
50#include <sound/rawmidi.h> 50#include <sound/rawmidi.h>
51#include <sound/asequencer.h>
51#include "usbaudio.h" 52#include "usbaudio.h"
52 53
53 54
@@ -1010,97 +1011,157 @@ static struct snd_rawmidi_substream *snd_usbmidi_find_substream(struct snd_usb_m
1010 * "(product) MIDI (n)" schema because they aren't external MIDI ports, 1011 * "(product) MIDI (n)" schema because they aren't external MIDI ports,
1011 * such as internal control or synthesizer ports. 1012 * such as internal control or synthesizer ports.
1012 */ 1013 */
1013static struct { 1014static struct port_info {
1014 u32 id; 1015 u32 id;
1015 int port; 1016 short int port;
1016 const char *name_format; 1017 short int voices;
1017} snd_usbmidi_port_names[] = { 1018 const char *name;
1019 unsigned int seq_flags;
1020} snd_usbmidi_port_info[] = {
1021#define PORT_INFO(vendor, product, num, name_, voices_, flags) \
1022 { .id = USB_ID(vendor, product), \
1023 .port = num, .voices = voices_, \
1024 .name = name_, .seq_flags = flags }
1025#define EXTERNAL_PORT(vendor, product, num, name) \
1026 PORT_INFO(vendor, product, num, name, 0, \
1027 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
1028 SNDRV_SEQ_PORT_TYPE_HARDWARE | \
1029 SNDRV_SEQ_PORT_TYPE_PORT)
1030#define CONTROL_PORT(vendor, product, num, name) \
1031 PORT_INFO(vendor, product, num, name, 0, \
1032 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
1033 SNDRV_SEQ_PORT_TYPE_HARDWARE)
1034#define ROLAND_SYNTH_PORT(vendor, product, num, name, voices) \
1035 PORT_INFO(vendor, product, num, name, voices, \
1036 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
1037 SNDRV_SEQ_PORT_TYPE_MIDI_GM | \
1038 SNDRV_SEQ_PORT_TYPE_MIDI_GM2 | \
1039 SNDRV_SEQ_PORT_TYPE_MIDI_GS | \
1040 SNDRV_SEQ_PORT_TYPE_MIDI_XG | \
1041 SNDRV_SEQ_PORT_TYPE_HARDWARE | \
1042 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER)
1043#define SOUNDCANVAS_PORT(vendor, product, num, name, voices) \
1044 PORT_INFO(vendor, product, num, name, voices, \
1045 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
1046 SNDRV_SEQ_PORT_TYPE_MIDI_GM | \
1047 SNDRV_SEQ_PORT_TYPE_MIDI_GM2 | \
1048 SNDRV_SEQ_PORT_TYPE_MIDI_GS | \
1049 SNDRV_SEQ_PORT_TYPE_MIDI_XG | \
1050 SNDRV_SEQ_PORT_TYPE_MIDI_MT32 | \
1051 SNDRV_SEQ_PORT_TYPE_HARDWARE | \
1052 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER)
1018 /* Roland UA-100 */ 1053 /* Roland UA-100 */
1019 { USB_ID(0x0582, 0x0000), 2, "%s Control" }, 1054 CONTROL_PORT(0x0582, 0x0000, 2, "%s Control"),
1020 /* Roland SC-8850 */ 1055 /* Roland SC-8850 */
1021 { USB_ID(0x0582, 0x0003), 0, "%s Part A" }, 1056 SOUNDCANVAS_PORT(0x0582, 0x0003, 0, "%s Part A", 128),
1022 { USB_ID(0x0582, 0x0003), 1, "%s Part B" }, 1057 SOUNDCANVAS_PORT(0x0582, 0x0003, 1, "%s Part B", 128),
1023 { USB_ID(0x0582, 0x0003), 2, "%s Part C" }, 1058 SOUNDCANVAS_PORT(0x0582, 0x0003, 2, "%s Part C", 128),
1024 { USB_ID(0x0582, 0x0003), 3, "%s Part D" }, 1059 SOUNDCANVAS_PORT(0x0582, 0x0003, 3, "%s Part D", 128),
1025 { USB_ID(0x0582, 0x0003), 4, "%s MIDI 1" }, 1060 EXTERNAL_PORT(0x0582, 0x0003, 4, "%s MIDI 1"),
1026 { USB_ID(0x0582, 0x0003), 5, "%s MIDI 2" }, 1061 EXTERNAL_PORT(0x0582, 0x0003, 5, "%s MIDI 2"),
1027 /* Roland U-8 */ 1062 /* Roland U-8 */
1028 { USB_ID(0x0582, 0x0004), 0, "%s MIDI" }, 1063 EXTERNAL_PORT(0x0582, 0x0004, 0, "%s MIDI"),
1029 { USB_ID(0x0582, 0x0004), 1, "%s Control" }, 1064 CONTROL_PORT(0x0582, 0x0004, 1, "%s Control"),
1030 /* Roland SC-8820 */ 1065 /* Roland SC-8820 */
1031 { USB_ID(0x0582, 0x0007), 0, "%s Part A" }, 1066 SOUNDCANVAS_PORT(0x0582, 0x0007, 0, "%s Part A", 64),
1032 { USB_ID(0x0582, 0x0007), 1, "%s Part B" }, 1067 SOUNDCANVAS_PORT(0x0582, 0x0007, 1, "%s Part B", 64),
1033 { USB_ID(0x0582, 0x0007), 2, "%s MIDI" }, 1068 EXTERNAL_PORT(0x0582, 0x0007, 2, "%s MIDI"),
1034 /* Roland SK-500 */ 1069 /* Roland SK-500 */
1035 { USB_ID(0x0582, 0x000b), 0, "%s Part A" }, 1070 SOUNDCANVAS_PORT(0x0582, 0x000b, 0, "%s Part A", 64),
1036 { USB_ID(0x0582, 0x000b), 1, "%s Part B" }, 1071 SOUNDCANVAS_PORT(0x0582, 0x000b, 1, "%s Part B", 64),
1037 { USB_ID(0x0582, 0x000b), 2, "%s MIDI" }, 1072 EXTERNAL_PORT(0x0582, 0x000b, 2, "%s MIDI"),
1038 /* Roland SC-D70 */ 1073 /* Roland SC-D70 */
1039 { USB_ID(0x0582, 0x000c), 0, "%s Part A" }, 1074 SOUNDCANVAS_PORT(0x0582, 0x000c, 0, "%s Part A", 64),
1040 { USB_ID(0x0582, 0x000c), 1, "%s Part B" }, 1075 SOUNDCANVAS_PORT(0x0582, 0x000c, 1, "%s Part B", 64),
1041 { USB_ID(0x0582, 0x000c), 2, "%s MIDI" }, 1076 EXTERNAL_PORT(0x0582, 0x000c, 2, "%s MIDI"),
1042 /* Edirol UM-880 */ 1077 /* Edirol UM-880 */
1043 { USB_ID(0x0582, 0x0014), 8, "%s Control" }, 1078 CONTROL_PORT(0x0582, 0x0014, 8, "%s Control"),
1044 /* Edirol SD-90 */ 1079 /* Edirol SD-90 */
1045 { USB_ID(0x0582, 0x0016), 0, "%s Part A" }, 1080 ROLAND_SYNTH_PORT(0x0582, 0x0016, 0, "%s Part A", 128),
1046 { USB_ID(0x0582, 0x0016), 1, "%s Part B" }, 1081 ROLAND_SYNTH_PORT(0x0582, 0x0016, 1, "%s Part B", 128),
1047 { USB_ID(0x0582, 0x0016), 2, "%s MIDI 1" }, 1082 EXTERNAL_PORT(0x0582, 0x0016, 2, "%s MIDI 1"),
1048 { USB_ID(0x0582, 0x0016), 3, "%s MIDI 2" }, 1083 EXTERNAL_PORT(0x0582, 0x0016, 3, "%s MIDI 2"),
1049 /* Edirol UM-550 */ 1084 /* Edirol UM-550 */
1050 { USB_ID(0x0582, 0x0023), 5, "%s Control" }, 1085 CONTROL_PORT(0x0582, 0x0023, 5, "%s Control"),
1051 /* Edirol SD-20 */ 1086 /* Edirol SD-20 */
1052 { USB_ID(0x0582, 0x0027), 0, "%s Part A" }, 1087 ROLAND_SYNTH_PORT(0x0582, 0x0027, 0, "%s Part A", 64),
1053 { USB_ID(0x0582, 0x0027), 1, "%s Part B" }, 1088 ROLAND_SYNTH_PORT(0x0582, 0x0027, 1, "%s Part B", 64),
1054 { USB_ID(0x0582, 0x0027), 2, "%s MIDI" }, 1089 EXTERNAL_PORT(0x0582, 0x0027, 2, "%s MIDI"),
1055 /* Edirol SD-80 */ 1090 /* Edirol SD-80 */
1056 { USB_ID(0x0582, 0x0029), 0, "%s Part A" }, 1091 ROLAND_SYNTH_PORT(0x0582, 0x0029, 0, "%s Part A", 128),
1057 { USB_ID(0x0582, 0x0029), 1, "%s Part B" }, 1092 ROLAND_SYNTH_PORT(0x0582, 0x0029, 1, "%s Part B", 128),
1058 { USB_ID(0x0582, 0x0029), 2, "%s MIDI 1" }, 1093 EXTERNAL_PORT(0x0582, 0x0029, 2, "%s MIDI 1"),
1059 { USB_ID(0x0582, 0x0029), 3, "%s MIDI 2" }, 1094 EXTERNAL_PORT(0x0582, 0x0029, 3, "%s MIDI 2"),
1060 /* Edirol UA-700 */ 1095 /* Edirol UA-700 */
1061 { USB_ID(0x0582, 0x002b), 0, "%s MIDI" }, 1096 EXTERNAL_PORT(0x0582, 0x002b, 0, "%s MIDI"),
1062 { USB_ID(0x0582, 0x002b), 1, "%s Control" }, 1097 CONTROL_PORT(0x0582, 0x002b, 1, "%s Control"),
1063 /* Roland VariOS */ 1098 /* Roland VariOS */
1064 { USB_ID(0x0582, 0x002f), 0, "%s MIDI" }, 1099 EXTERNAL_PORT(0x0582, 0x002f, 0, "%s MIDI"),
1065 { USB_ID(0x0582, 0x002f), 1, "%s External MIDI" }, 1100 EXTERNAL_PORT(0x0582, 0x002f, 1, "%s External MIDI"),
1066 { USB_ID(0x0582, 0x002f), 2, "%s Sync" }, 1101 EXTERNAL_PORT(0x0582, 0x002f, 2, "%s Sync"),
1067 /* Edirol PCR */ 1102 /* Edirol PCR */
1068 { USB_ID(0x0582, 0x0033), 0, "%s MIDI" }, 1103 EXTERNAL_PORT(0x0582, 0x0033, 0, "%s MIDI"),
1069 { USB_ID(0x0582, 0x0033), 1, "%s 1" }, 1104 EXTERNAL_PORT(0x0582, 0x0033, 1, "%s 1"),
1070 { USB_ID(0x0582, 0x0033), 2, "%s 2" }, 1105 EXTERNAL_PORT(0x0582, 0x0033, 2, "%s 2"),
1071 /* BOSS GS-10 */ 1106 /* BOSS GS-10 */
1072 { USB_ID(0x0582, 0x003b), 0, "%s MIDI" }, 1107 EXTERNAL_PORT(0x0582, 0x003b, 0, "%s MIDI"),
1073 { USB_ID(0x0582, 0x003b), 1, "%s Control" }, 1108 CONTROL_PORT(0x0582, 0x003b, 1, "%s Control"),
1074 /* Edirol UA-1000 */ 1109 /* Edirol UA-1000 */
1075 { USB_ID(0x0582, 0x0044), 0, "%s MIDI" }, 1110 EXTERNAL_PORT(0x0582, 0x0044, 0, "%s MIDI"),
1076 { USB_ID(0x0582, 0x0044), 1, "%s Control" }, 1111 CONTROL_PORT(0x0582, 0x0044, 1, "%s Control"),
1077 /* Edirol UR-80 */ 1112 /* Edirol UR-80 */
1078 { USB_ID(0x0582, 0x0048), 0, "%s MIDI" }, 1113 EXTERNAL_PORT(0x0582, 0x0048, 0, "%s MIDI"),
1079 { USB_ID(0x0582, 0x0048), 1, "%s 1" }, 1114 EXTERNAL_PORT(0x0582, 0x0048, 1, "%s 1"),
1080 { USB_ID(0x0582, 0x0048), 2, "%s 2" }, 1115 EXTERNAL_PORT(0x0582, 0x0048, 2, "%s 2"),
1081 /* Edirol PCR-A */ 1116 /* Edirol PCR-A */
1082 { USB_ID(0x0582, 0x004d), 0, "%s MIDI" }, 1117 EXTERNAL_PORT(0x0582, 0x004d, 0, "%s MIDI"),
1083 { USB_ID(0x0582, 0x004d), 1, "%s 1" }, 1118 EXTERNAL_PORT(0x0582, 0x004d, 1, "%s 1"),
1084 { USB_ID(0x0582, 0x004d), 2, "%s 2" }, 1119 EXTERNAL_PORT(0x0582, 0x004d, 2, "%s 2"),
1085 /* Edirol UM-3EX */ 1120 /* Edirol UM-3EX */
1086 { USB_ID(0x0582, 0x009a), 3, "%s Control" }, 1121 CONTROL_PORT(0x0582, 0x009a, 3, "%s Control"),
1087 /* M-Audio MidiSport 8x8 */ 1122 /* M-Audio MidiSport 8x8 */
1088 { USB_ID(0x0763, 0x1031), 8, "%s Control" }, 1123 CONTROL_PORT(0x0763, 0x1031, 8, "%s Control"),
1089 { USB_ID(0x0763, 0x1033), 8, "%s Control" }, 1124 CONTROL_PORT(0x0763, 0x1033, 8, "%s Control"),
1090 /* MOTU Fastlane */ 1125 /* MOTU Fastlane */
1091 { USB_ID(0x07fd, 0x0001), 0, "%s MIDI A" }, 1126 EXTERNAL_PORT(0x07fd, 0x0001, 0, "%s MIDI A"),
1092 { USB_ID(0x07fd, 0x0001), 1, "%s MIDI B" }, 1127 EXTERNAL_PORT(0x07fd, 0x0001, 1, "%s MIDI B"),
1093 /* Emagic Unitor8/AMT8/MT4 */ 1128 /* Emagic Unitor8/AMT8/MT4 */
1094 { USB_ID(0x086a, 0x0001), 8, "%s Broadcast" }, 1129 EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"),
1095 { USB_ID(0x086a, 0x0002), 8, "%s Broadcast" }, 1130 EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"),
1096 { USB_ID(0x086a, 0x0003), 4, "%s Broadcast" }, 1131 EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"),
1097}; 1132};
1098 1133
1134static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number)
1135{
1136 int i;
1137
1138 for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_info); ++i) {
1139 if (snd_usbmidi_port_info[i].id == umidi->chip->usb_id &&
1140 snd_usbmidi_port_info[i].port == number)
1141 return &snd_usbmidi_port_info[i];
1142 }
1143 return NULL;
1144}
1145
1146static void snd_usbmidi_get_port_info(struct snd_rawmidi *rmidi, int number,
1147 struct snd_seq_port_info *seq_port_info)
1148{
1149 struct snd_usb_midi *umidi = rmidi->private_data;
1150 struct port_info *port_info;
1151
1152 /* TODO: read port flags from descriptors */
1153 port_info = find_port_info(umidi, number);
1154 if (port_info) {
1155 seq_port_info->type = port_info->seq_flags;
1156 seq_port_info->midi_voices = port_info->voices;
1157 }
1158}
1159
1099static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi, 1160static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi,
1100 int stream, int number, 1161 int stream, int number,
1101 struct snd_rawmidi_substream ** rsubstream) 1162 struct snd_rawmidi_substream ** rsubstream)
1102{ 1163{
1103 int i; 1164 struct port_info *port_info;
1104 const char *name_format; 1165 const char *name_format;
1105 1166
1106 struct snd_rawmidi_substream *substream = snd_usbmidi_find_substream(umidi, stream, number); 1167 struct snd_rawmidi_substream *substream = snd_usbmidi_find_substream(umidi, stream, number);
@@ -1110,14 +1171,8 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi,
1110 } 1171 }
1111 1172
1112 /* TODO: read port name from jack descriptor */ 1173 /* TODO: read port name from jack descriptor */
1113 name_format = "%s MIDI %d"; 1174 port_info = find_port_info(umidi, number);
1114 for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_names); ++i) { 1175 name_format = port_info ? port_info->name : "%s MIDI %d";
1115 if (snd_usbmidi_port_names[i].id == umidi->chip->usb_id &&
1116 snd_usbmidi_port_names[i].port == number) {
1117 name_format = snd_usbmidi_port_names[i].name_format;
1118 break;
1119 }
1120 }
1121 snprintf(substream->name, sizeof(substream->name), 1176 snprintf(substream->name, sizeof(substream->name),
1122 name_format, umidi->chip->card->shortname, number + 1); 1177 name_format, umidi->chip->card->shortname, number + 1);
1123 1178
@@ -1358,7 +1413,7 @@ static int snd_usbmidi_detect_yamaha(struct snd_usb_midi* umidi,
1358 for (cs_desc = hostif->extra; 1413 for (cs_desc = hostif->extra;
1359 cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2; 1414 cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2;
1360 cs_desc += cs_desc[0]) { 1415 cs_desc += cs_desc[0]) {
1361 if (cs_desc[1] == CS_AUDIO_INTERFACE) { 1416 if (cs_desc[1] == USB_DT_CS_INTERFACE) {
1362 if (cs_desc[2] == MIDI_IN_JACK) 1417 if (cs_desc[2] == MIDI_IN_JACK)
1363 endpoint->in_cables = (endpoint->in_cables << 1) | 1; 1418 endpoint->in_cables = (endpoint->in_cables << 1) | 1;
1364 else if (cs_desc[2] == MIDI_OUT_JACK) 1419 else if (cs_desc[2] == MIDI_OUT_JACK)
@@ -1457,6 +1512,10 @@ static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi* umidi,
1457 return 0; 1512 return 0;
1458} 1513}
1459 1514
1515static struct snd_rawmidi_global_ops snd_usbmidi_ops = {
1516 .get_port_info = snd_usbmidi_get_port_info,
1517};
1518
1460static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi, 1519static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi,
1461 int out_ports, int in_ports) 1520 int out_ports, int in_ports)
1462{ 1521{
@@ -1472,6 +1531,7 @@ static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi,
1472 rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | 1531 rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
1473 SNDRV_RAWMIDI_INFO_INPUT | 1532 SNDRV_RAWMIDI_INFO_INPUT |
1474 SNDRV_RAWMIDI_INFO_DUPLEX; 1533 SNDRV_RAWMIDI_INFO_DUPLEX;
1534 rmidi->ops = &snd_usbmidi_ops;
1475 rmidi->private_data = umidi; 1535 rmidi->private_data = umidi;
1476 rmidi->private_free = snd_usbmidi_rawmidi_free; 1536 rmidi->private_free = snd_usbmidi_rawmidi_free;
1477 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_usbmidi_output_ops); 1537 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_usbmidi_output_ops);
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index ce86283ee0fa..491e975a0c87 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -46,6 +46,27 @@
46/* ignore error from controls - for debugging */ 46/* ignore error from controls - for debugging */
47/* #define IGNORE_CTL_ERROR */ 47/* #define IGNORE_CTL_ERROR */
48 48
49/*
50 * Sound Blaster remote control configuration
51 *
52 * format of remote control data:
53 * Extigy: xx 00
54 * Audigy 2 NX: 06 80 xx 00 00 00
55 * Live! 24-bit: 06 80 xx yy 22 83
56 */
57static const struct rc_config {
58 u32 usb_id;
59 u8 offset;
60 u8 length;
61 u8 packet_length;
62 u8 mute_mixer_id;
63 u32 mute_code;
64} rc_configs[] = {
65 { USB_ID(0x041e, 0x3000), 0, 1, 2, 18, 0x0013 }, /* Extigy */
66 { USB_ID(0x041e, 0x3020), 2, 1, 6, 18, 0x0013 }, /* Audigy 2 NX */
67 { USB_ID(0x041e, 0x3040), 2, 2, 6, 2, 0x6e91 }, /* Live! 24-bit */
68};
69
49struct usb_mixer_interface { 70struct usb_mixer_interface {
50 struct snd_usb_audio *chip; 71 struct snd_usb_audio *chip;
51 unsigned int ctrlif; 72 unsigned int ctrlif;
@@ -55,11 +76,7 @@ struct usb_mixer_interface {
55 struct usb_mixer_elem_info **id_elems; /* array[256], indexed by unit id */ 76 struct usb_mixer_elem_info **id_elems; /* array[256], indexed by unit id */
56 77
57 /* Sound Blaster remote control stuff */ 78 /* Sound Blaster remote control stuff */
58 enum { 79 const struct rc_config *rc_cfg;
59 RC_NONE,
60 RC_EXTIGY,
61 RC_AUDIGY2NX,
62 } rc_type;
63 unsigned long rc_hwdep_open; 80 unsigned long rc_hwdep_open;
64 u32 rc_code; 81 u32 rc_code;
65 wait_queue_head_t rc_waitq; 82 wait_queue_head_t rc_waitq;
@@ -1647,7 +1664,7 @@ static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer,
1647static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer, 1664static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
1648 int unitid) 1665 int unitid)
1649{ 1666{
1650 if (mixer->rc_type == RC_NONE) 1667 if (!mixer->rc_cfg)
1651 return; 1668 return;
1652 /* unit ids specific to Extigy/Audigy 2 NX: */ 1669 /* unit ids specific to Extigy/Audigy 2 NX: */
1653 switch (unitid) { 1670 switch (unitid) {
@@ -1732,20 +1749,19 @@ static void snd_usb_soundblaster_remote_complete(struct urb *urb,
1732 struct pt_regs *regs) 1749 struct pt_regs *regs)
1733{ 1750{
1734 struct usb_mixer_interface *mixer = urb->context; 1751 struct usb_mixer_interface *mixer = urb->context;
1735 /* 1752 const struct rc_config *rc = mixer->rc_cfg;
1736 * format of remote control data:
1737 * Extigy: xx 00
1738 * Audigy 2 NX: 06 80 xx 00 00 00
1739 */
1740 int offset = mixer->rc_type == RC_EXTIGY ? 0 : 2;
1741 u32 code; 1753 u32 code;
1742 1754
1743 if (urb->status < 0 || urb->actual_length <= offset) 1755 if (urb->status < 0 || urb->actual_length < rc->packet_length)
1744 return; 1756 return;
1745 code = mixer->rc_buffer[offset]; 1757
1758 code = mixer->rc_buffer[rc->offset];
1759 if (rc->length == 2)
1760 code |= mixer->rc_buffer[rc->offset + 1] << 8;
1761
1746 /* the Mute button actually changes the mixer control */ 1762 /* the Mute button actually changes the mixer control */
1747 if (code == 13) 1763 if (code == rc->mute_code)
1748 snd_usb_mixer_notify_id(mixer, 18); 1764 snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
1749 mixer->rc_code = code; 1765 mixer->rc_code = code;
1750 wmb(); 1766 wmb();
1751 wake_up(&mixer->rc_waitq); 1767 wake_up(&mixer->rc_waitq);
@@ -1801,21 +1817,17 @@ static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *f
1801static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer) 1817static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
1802{ 1818{
1803 struct snd_hwdep *hwdep; 1819 struct snd_hwdep *hwdep;
1804 int err, len; 1820 int err, len, i;
1805 1821
1806 switch (mixer->chip->usb_id) { 1822 for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
1807 case USB_ID(0x041e, 0x3000): 1823 if (rc_configs[i].usb_id == mixer->chip->usb_id)
1808 mixer->rc_type = RC_EXTIGY; 1824 break;
1809 len = 2; 1825 if (i >= ARRAY_SIZE(rc_configs))
1810 break;
1811 case USB_ID(0x041e, 0x3020):
1812 mixer->rc_type = RC_AUDIGY2NX;
1813 len = 6;
1814 break;
1815 default:
1816 return 0; 1826 return 0;
1817 } 1827 mixer->rc_cfg = &rc_configs[i];
1818 1828
1829 len = mixer->rc_cfg->packet_length;
1830
1819 init_waitqueue_head(&mixer->rc_waitq); 1831 init_waitqueue_head(&mixer->rc_waitq);
1820 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep); 1832 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
1821 if (err < 0) 1833 if (err < 0)
@@ -1998,7 +2010,7 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif)
1998 if ((err = snd_audigy2nx_controls_create(mixer)) < 0) 2010 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
1999 goto _error; 2011 goto _error;
2000 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry)) 2012 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry))
2001 snd_info_set_text_ops(entry, mixer, 1024, 2013 snd_info_set_text_ops(entry, mixer,
2002 snd_audigy2nx_proc_read); 2014 snd_audigy2nx_proc_read);
2003 } 2015 }
2004 2016
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index fe67a92e2a1a..88b72b52590f 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -632,7 +632,7 @@ static int usX2Y_pcms_lock_check(struct snd_card *card)
632 for (s = 0; s < 2; ++s) { 632 for (s = 0; s < 2; ++s) {
633 struct snd_pcm_substream *substream; 633 struct snd_pcm_substream *substream;
634 substream = pcm->streams[s].substream; 634 substream = pcm->streams[s].substream;
635 if (substream && substream->ffile != NULL) 635 if (SUBSTREAM_BUSY(substream))
636 err = -EBUSY; 636 err = -EBUSY;
637 } 637 }
638 } 638 }