http://linux-sound.bkbits.net/linux-sound perex@suse.cz|ChangeSet|20041111181827|47279 perex # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/11/11 19:18:27+01:00 perex@suse.cz # ALSA 1.0.7 # # include/sound/version.h # 2004/11/11 19:17:49+01:00 perex@suse.cz +2 -2 # ALSA 1.0.7 # # ChangeSet # 2004/11/11 11:52:13+01:00 perex@suse.cz # [ALSA] nonblock_open=1 by default for OSS PCM API emulation # # Documentation,ALSA<-OSS emulation # # # Signed-off-by: Jaroslav Kysela # # sound/core/oss/pcm_oss.c # 2004/11/10 23:41:05+01:00 perex@suse.cz +1 -1 # [ALSA] nonblock_open=1 by default for OSS PCM API emulation # # D:2004/11/11 06:41:03 # C:Documentation,ALSA<-OSS emulation # F:Documentation/OSS-Emulation.txt:1.7->1.8 # F:core/oss/pcm_oss.c:1.80->1.81 # L: # Signed-off-by: Jaroslav Kysela # # Documentation/sound/alsa/OSS-Emulation.txt # 2004/11/10 23:41:03+01:00 perex@suse.cz +5 -6 # [ALSA] nonblock_open=1 by default for OSS PCM API emulation # # D:2004/11/11 06:41:03 # C:Documentation,ALSA<-OSS emulation # F:Documentation/OSS-Emulation.txt:1.7->1.8 # F:core/oss/pcm_oss.c:1.80->1.81 # L: # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/11/11 11:51:08+01:00 perex@suse.cz # [ALSA] fix parsing of mixer unit descriptors # # USB generic driver # MU descriptor parsing code completely rewritten; the old code confused # the number of input audio channel clusters and the number of input # channels. Furthermore, check all bmControls bits so that mixer # controls are created even if the first output channel doesn't have # a control. # # Signed-off-by: Clemens Ladisch # # sound/usb/usbmixer.c # 2004/11/10 10:29:55+01:00 perex@suse.cz +40 -19 # [ALSA] fix parsing of mixer unit descriptors # # D:2004/11/10 17:29:55 # C:USB generic driver # F:usb/usbmixer.c:1.32->1.33 # L:MU descriptor parsing code completely rewritten; the old code confused # L:the number of input audio channel clusters and the number of input # L:channels. Furthermore, check all bmControls bits so that mixer # L:controls are created even if the first output channel doesn't have # L:a control. # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/11/11 11:50:04+01:00 perex@suse.cz # [ALSA] read bmControls array in correct order # # USB generic driver # The driver used some code from audio.c that reads the bmControl array # backwards; this would not work here as we get a pointer to the # beginning of the array. # # Signed-off-by: Clemens Ladisch # # sound/usb/usbmixer.c # 2004/11/10 06:48:03+01:00 perex@suse.cz +1 -1 # [ALSA] read bmControls array in correct order # # D:2004/11/10 13:48:03 # C:USB generic driver # F:usb/usbmixer.c:1.31->1.32 # L:The driver used some code from audio.c that reads the bmControl array # L:backwards; this would not work here as we get a pointer to the # L:beginning of the array. # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/11/11 11:48:57+01:00 perex@suse.cz # [ALSA] handle missing control bitmap when parsing MUDs # # USB generic driver # The AudioTrak Maya44 USB has a mixer unit descriptor without a # bmControl field; handle this as if all bits are zero. # # Signed-off-by: Clemens Ladisch # # sound/usb/usbmixer.c # 2004/11/10 06:44:15+01:00 perex@suse.cz +5 -2 # [ALSA] handle missing control bitmap when parsing MUDs # # D:2004/11/10 13:44:15 # C:USB generic driver # F:usb/usbmixer.c:1.30->1.31 # L:The AudioTrak Maya44 USB has a mixer unit descriptor without a # L:bmControl field; handle this as if all bits are zero. # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/11/11 11:47:49+01:00 perex@suse.cz # [ALSA] emu10k1 - fixed remaining problems with new DSP code loading # # EMU10K1/EMU10K2 driver # # # Signed-off-by: Jaroslav Kysela # # sound/pci/emu10k1/emufx.c # 2004/11/10 04:54:36+01:00 perex@suse.cz +12 -22 # [ALSA] emu10k1 - fixed remaining problems with new DSP code loading # # D:2004/11/10 11:54:36 # C:EMU10K1/EMU10K2 driver # F:pci/emu10k1/emufx.c:1.62->1.63 # L: # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/11/11 11:46:44+01:00 perex@suse.cz # [ALSA] [emu10k1] add interval timer support # # EMU10K1/EMU10K2 driver # # # Signed-off-by: Lee Revell # Signed-off-by: Takashi Iwai # # sound/pci/emu10k1/irq.c # 2004/11/10 02:49:12+01:00 perex@suse.cz +2 -2 # [ALSA] [emu10k1] add interval timer support # # D:2004/11/10 09:49:11 # C:EMU10K1/EMU10K2 driver # F:include/emu10k1.h:1.49->1.50 # F:pci/emu10k1/Makefile:1.10->1.11 # F:pci/emu10k1/emu10k1.c:1.28->1.29 # F:pci/emu10k1/irq.c:1.10->1.11 # F:pci/emu10k1/timer.c:INITIAL->1.1 # L: # Signed-off-by: Lee Revell # Signed-off-by: Takashi Iwai # # sound/pci/emu10k1/emu10k1.c # 2004/11/10 02:49:12+01:00 perex@suse.cz +6 -0 # [ALSA] [emu10k1] add interval timer support # # D:2004/11/10 09:49:11 # C:EMU10K1/EMU10K2 driver # F:include/emu10k1.h:1.49->1.50 # F:pci/emu10k1/Makefile:1.10->1.11 # F:pci/emu10k1/emu10k1.c:1.28->1.29 # F:pci/emu10k1/irq.c:1.10->1.11 # F:pci/emu10k1/timer.c:INITIAL->1.1 # L: # Signed-off-by: Lee Revell # Signed-off-by: Takashi Iwai # # sound/pci/emu10k1/Makefile # 2004/11/10 02:49:12+01:00 perex@suse.cz +1 -1 # [ALSA] [emu10k1] add interval timer support # # D:2004/11/10 09:49:11 # C:EMU10K1/EMU10K2 driver # F:include/emu10k1.h:1.49->1.50 # F:pci/emu10k1/Makefile:1.10->1.11 # F:pci/emu10k1/emu10k1.c:1.28->1.29 # F:pci/emu10k1/irq.c:1.10->1.11 # F:pci/emu10k1/timer.c:INITIAL->1.1 # L: # Signed-off-by: Lee Revell # Signed-off-by: Takashi Iwai # # include/sound/emu10k1.h # 2004/11/10 02:49:11+01:00 perex@suse.cz +4 -0 # [ALSA] [emu10k1] add interval timer support # # D:2004/11/10 09:49:11 # C:EMU10K1/EMU10K2 driver # F:include/emu10k1.h:1.49->1.50 # F:pci/emu10k1/Makefile:1.10->1.11 # F:pci/emu10k1/emu10k1.c:1.28->1.29 # F:pci/emu10k1/irq.c:1.10->1.11 # F:pci/emu10k1/timer.c:INITIAL->1.1 # L: # Signed-off-by: Lee Revell # Signed-off-by: Takashi Iwai # # sound/pci/emu10k1/timer.c # 2004/11/11 10:45:36+01:00 perex@suse.cz +99 -0 # [ALSA] [emu10k1] add interval timer support # # D:2004/11/10 09:49:11 # C:EMU10K1/EMU10K2 driver # F:include/emu10k1.h:1.49->1.50 # F:pci/emu10k1/Makefile:1.10->1.11 # F:pci/emu10k1/emu10k1.c:1.28->1.29 # F:pci/emu10k1/irq.c:1.10->1.11 # F:pci/emu10k1/timer.c:INITIAL->1.1 # L: # Signed-off-by: Lee Revell # Signed-off-by: Takashi Iwai # # sound/pci/emu10k1/timer.c # 2004/11/11 10:45:36+01:00 perex@suse.cz +0 -0 # BitKeeper file /home/perex/bk/linux-sound/work/sound/pci/emu10k1/timer.c # # ChangeSet # 2004/11/11 11:45:39+01:00 perex@suse.cz # [ALSA] Fixed issues with Abit AV8 # # VIA82xx driver # Added Abit AV8 sound card to the white list to use # VIA_DXS_NO_VRA by default. This resolves issues with # programs wanting to use 41k streams. It also fixes # gstreamer issue with alsasink module interaction. # # Signed-off-by: Jerone Young # Signed-off-by: Takashi Iwai # # sound/pci/via82xx.c # 2004/11/09 10:43:36+01:00 perex@suse.cz +1 -0 # [ALSA] Fixed issues with Abit AV8 # # D:2004/11/09 17:43:36 # C:VIA82xx driver # F:pci/via82xx.c:1.126->1.127 # L:Added Abit AV8 sound card to the white list to use # L:VIA_DXS_NO_VRA by default. This resolves issues with # L:programs wanting to use 41k streams. It also fixes # L:gstreamer issue with alsasink module interaction. # Signed-off-by: Jerone Young # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/11/11 11:44:32+01:00 perex@suse.cz # [ALSA] Add subvendor ID to the pci id table of vx222 driver # # Digigram VX222 driver # The subsystem ID is added to the pci id table of vx222 driver # to make the matching more strict since it (PLX) conflicts with # other devices. # # Signed-off-by: Takashi Iwai # # sound/pci/vx222/vx222.c # 2004/11/09 09:05:37+01:00 perex@suse.cz +2 -2 # [ALSA] Add subvendor ID to the pci id table of vx222 driver # # D:2004/11/09 16:05:37 # C:Digigram VX222 driver # F:pci/vx222/vx222.c:1.9->1.10 # L:The subsystem ID is added to the pci id table of vx222 driver # L:to make the matching more strict since it (PLX) conflicts with # L:other devices. # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/11/11 11:43:26+01:00 perex@suse.cz # [ALSA] removes unneeded spin_lock_irqsave()s from snd-es1968 # # ES1968 driver # spin_lock_irqsave(&chip->reg_lock) was called a second time in sequence from # snd_es1968_bob_start() called from es1968_measure_clock(). # While this didn't cause harm on my UP laptop with mainline kernels, # it made 'insmod snd-es1968' hang on kernel 2.6.9-mm1-RT-V0.6.9. # The patch assumes that 2 callpaths don't need explicit spinlock protection: # 1: The trigger callback, because it is called with IRQs disabled. # 2. PM's suspend/resume callbacks, because those are called while ortdinary # user processes are frozen. # Thus the spin_lock_irqsave(&chip->reg_lock) calls in snd_es1968_bob_start() # / snd_es1968_bob_stop() are not needed. # # Signed-off-by: Karsten Wiese # Signed-off-by: Takashi Iwai # # sound/pci/es1968.c # 2004/11/09 02:18:44+01:00 perex@suse.cz +0 -6 # [ALSA] removes unneeded spin_lock_irqsave()s from snd-es1968 # # D:2004/11/09 09:18:44 # C:ES1968 driver # F:pci/es1968.c:1.77->1.78 # L:spin_lock_irqsave(&chip->reg_lock) was called a second time in sequence from # L:snd_es1968_bob_start() called from es1968_measure_clock(). # L:While this didn't cause harm on my UP laptop with mainline kernels, # L:it made 'insmod snd-es1968' hang on kernel 2.6.9-mm1-RT-V0.6.9. # L:The patch assumes that 2 callpaths don't need explicit spinlock protection: # L:1: The trigger callback, because it is called with IRQs disabled. # L:2. PM's suspend/resume callbacks, because those are called while ortdinary # L: user processes are frozen. # L: Thus the spin_lock_irqsave(&chip->reg_lock) calls in snd_es1968_bob_start() # L: / snd_es1968_bob_stop() are not needed. # Signed-off-by: Karsten Wiese # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/11/11 11:42:23+01:00 perex@suse.cz # [ALSA] Fixed the description of module_parm_array() # # Documentation # Fixed the description about module_param_array() for the latest change. # # Signed-off-by: Takashi Iwai # # Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl # 2004/11/09 02:16:33+01:00 perex@suse.cz +3 -7 # [ALSA] Fixed the description of module_parm_array() # # D:2004/11/09 09:16:33 # C:Documentation # F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.42->1.43 # L:Fixed the description about module_param_array() for the latest change. # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/11/11 11:41:13+01:00 perex@suse.cz # [ALSA] remove snd_seq_simple_id # # Instrument layer,GUS Library,Trident driver # remove uses of the snd_seq_simple_id symbol because it is # no longer exported # # Signed-off-by: Clemens Ladisch # # sound/pci/trident/trident_synth.c # 2004/11/09 01:05:14+01:00 perex@suse.cz +1 -1 # [ALSA] remove snd_seq_simple_id # # D:2004/11/09 08:05:14 # C:Instrument layer,GUS Library,Trident driver # F:include/ainstr_simple.h:1.4->1.5 # F:isa/gus/gus_sample.c:1.5->1.6 # F:pci/trident/trident_synth.c:1.15->1.16 # L:remove uses of the snd_seq_simple_id symbol because it is # L:no longer exported # Signed-off-by: Clemens Ladisch # # sound/isa/gus/gus_sample.c # 2004/11/09 01:05:14+01:00 perex@suse.cz +1 -1 # [ALSA] remove snd_seq_simple_id # # D:2004/11/09 08:05:14 # C:Instrument layer,GUS Library,Trident driver # F:include/ainstr_simple.h:1.4->1.5 # F:isa/gus/gus_sample.c:1.5->1.6 # F:pci/trident/trident_synth.c:1.15->1.16 # L:remove uses of the snd_seq_simple_id symbol because it is # L:no longer exported # Signed-off-by: Clemens Ladisch # # include/sound/ainstr_simple.h # 2004/11/09 01:05:14+01:00 perex@suse.cz +0 -2 # [ALSA] remove snd_seq_simple_id # # D:2004/11/09 08:05:14 # C:Instrument layer,GUS Library,Trident driver # F:include/ainstr_simple.h:1.4->1.5 # F:isa/gus/gus_sample.c:1.5->1.6 # F:pci/trident/trident_synth.c:1.15->1.16 # L:remove uses of the snd_seq_simple_id symbol because it is # L:no longer exported # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/11/11 11:40:08+01:00 perex@suse.cz # [ALSA] Added SNDRV_HWDEP_IFACE_BLUETOOTH # # ALSA Core # # # Signed-off-by: Marcel Holtmann # Signed-off-by: Jaroslav Kysela # # include/sound/asound.h # 2004/11/08 05:20:03+01:00 perex@suse.cz +2 -1 # [ALSA] Added SNDRV_HWDEP_IFACE_BLUETOOTH # # D:2004/11/08 12:20:03 # C:ALSA Core # F:include/asound.h:1.45->1.46 # L: # Signed-off-by: Marcel Holtmann # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/11/11 11:39:05+01:00 perex@suse.cz # [ALSA] emu10k1 - another attempt to correct the new emufx DSP code # # EMU10K1/EMU10K2 driver # # # Signed-off-by: Jaroslav Kysela # # sound/pci/emu10k1/emufx.c # 2004/11/07 23:42:44+01:00 perex@suse.cz +8 -6 # [ALSA] emu10k1 - another attempt to correct the new emufx DSP code # # D:2004/11/08 06:42:44 # C:EMU10K1/EMU10K2 driver # F:pci/emu10k1/emufx.c:1.61->1.62 # L: # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/11/11 11:37:58+01:00 perex@suse.cz # [ALSA] replace schedule_timeout() with msleep() # # SPARC cs4231 driver # Uses msleep() instead of schedule_timeout() to guarantee the task # delays as expected. # # Signed-off-by: Nishanth Aravamudan # Signed-off-by: Clemens Ladisch # # sound/sparc/cs4231.c # 2004/11/04 00:57:41+01:00 perex@suse.cz +8 -9 # [ALSA] replace schedule_timeout() with msleep() # # D:2004/11/04 07:57:41 # C:SPARC cs4231 driver # F:sparc/cs4231.c:1.18->1.19 # L:Uses msleep() instead of schedule_timeout() to guarantee the task # L:delays as expected. # Signed-off-by: Nishanth Aravamudan # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/11/11 11:22:49+01:00 perex@suse.cz # [ALSA] replace schedule_timeout() with msleep() # # CS4231 driver # Uses msleep() instead of schedule_timeout() to guarantee # the task delays as expected. This lead to several related changes, as # the current code assumes the value of HZ is 100. Use timeout as an # iteration variable to count out how many 10ms delays should be used. # # Signed-off-by: Nishanth Aravamudan # Signed-off-by: Clemens Ladisch # # sound/isa/cs423x/cs4231_lib.c # 2004/11/03 02:10:40+01:00 perex@suse.cz +6 -15 # [ALSA] replace schedule_timeout() with msleep() # # CS4231 driver # Uses msleep() instead of schedule_timeout() to guarantee # the task delays as expected. This lead to several related changes, as # the current code assumes the value of HZ is 100. Use timeout as an # iteration variable to count out how many 10ms delays should be used. # # Signed-off-by: Nishanth Aravamudan # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/11/11 10:09:08+01:00 perex@suse.cz # Merge # # sound/core/info.c # 2004/11/11 10:08:40+01:00 perex@suse.cz +1 -5 # SCCS merged # # ChangeSet # 2004/10/30 15:01:05+02:00 perex@suse.cz # [ALSA] emu10k1 - fixes against the last emufx changes # # EMU10K1/EMU10K2 driver # The indirect pointers are allocated correctly now for default DSP code. # Also, one bug in emu10k1_fx8010_code_t has been fixed as well. # # Signed-off-by: Jaroslav Kysela # # sound/pci/emu10k1/emufx.c # 2004/10/30 02:44:20+02:00 perex@suse.cz +38 -24 # [ALSA] emu10k1 - fixes against the last emufx changes # # D:2004/10/30 08:44:19 # C:EMU10K1/EMU10K2 driver # F:include/emu10k1.h:1.48->1.49 # F:pci/emu10k1/emufx.c:1.60->1.61 # L:The indirect pointers are allocated correctly now for default DSP code. # L:Also, one bug in emu10k1_fx8010_code_t has been fixed as well. # Signed-off-by: Jaroslav Kysela # # include/sound/emu10k1.h # 2004/10/30 02:44:19+02:00 perex@suse.cz +3 -3 # [ALSA] emu10k1 - fixes against the last emufx changes # # D:2004/10/30 08:44:19 # C:EMU10K1/EMU10K2 driver # F:include/emu10k1.h:1.48->1.49 # F:pci/emu10k1/emufx.c:1.60->1.61 # L:The indirect pointers are allocated correctly now for default DSP code. # L:Also, one bug in emu10k1_fx8010_code_t has been fixed as well. # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/10/29 17:40:37+02:00 perex@suse.cz # [ALSA] fixed emu10k1_fx8010_code_t structure to be less than 8192 bytes # # EMU10K1/EMU10K2 driver # This patch fixes emu10k1_fx8010_code_t structure using indirect pointers # to be less than 8192 bytes to follow the ioctl semantics. # # Signed-off-by: Jaroslav Kysela # # sound/pci/emu10k1/emufx.c # 2004/10/28 08:24:17+02:00 perex@suse.cz +100 -55 # [ALSA] fixed emu10k1_fx8010_code_t structure to be less than 8192 bytes # # D:2004/10/28 14:24:17 # C:EMU10K1/EMU10K2 driver # F:include/emu10k1.h:1.47->1.48 # F:pci/emu10k1/emufx.c:1.59->1.60 # L:This patch fixes emu10k1_fx8010_code_t structure using indirect pointers # L:to be less than 8192 bytes to follow the ioctl semantics. # Signed-off-by: Jaroslav Kysela # # include/sound/emu10k1.h # 2004/10/28 08:24:17+02:00 perex@suse.cz +4 -4 # [ALSA] fixed emu10k1_fx8010_code_t structure to be less than 8192 bytes # # D:2004/10/28 14:24:17 # C:EMU10K1/EMU10K2 driver # F:include/emu10k1.h:1.47->1.48 # F:pci/emu10k1/emufx.c:1.59->1.60 # L:This patch fixes emu10k1_fx8010_code_t structure using indirect pointers # L:to be less than 8192 bytes to follow the ioctl semantics. # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/10/29 17:19:01+02:00 perex@suse.cz # [ALSA] remove kernel version info from proc file # # ALSA Core # The kernel version information isn't necessary for the driver # in the kernel tree, so move it to the alsa-driver package. # # This removes a dependency to . # # Signed-off-by: Clemens Ladisch # # sound/core/info.c # 2004/10/28 02:10:50+02:00 perex@suse.cz +3 -12 # [ALSA] remove kernel version info from proc file # # D:2004/10/28 08:10:50 # C:ALSA Core # F:core/info.c:1.48->1.49 # L:The kernel version information isn't necessary for the driver # L:in the kernel tree, so move it to the alsa-driver package. # L: # L:This removes a dependency to . # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/10/29 17:17:57+02:00 perex@suse.cz # [ALSA] Limit parity error messages # # BT87x driver # Some systems generate tons of PCI parity errors, so shut up # when more than 20 have been detected. # # Signed-off-by: Clemens Ladisch # # sound/pci/bt87x.c # 2004/10/27 11:51:57+02:00 perex@suse.cz +43 -18 # [ALSA] Limit parity error messages # # D:2004/10/27 17:51:57 # C:BT87x driver # F:pci/bt87x.c:1.16->1.17 # L:Some systems generate tons of PCI parity errors, so shut up # L:when more than 20 have been detected. # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/10/29 17:16:52+02:00 perex@suse.cz # [ALSA] remove dead exports # # ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # Alsa currently has tons of dead exports, often with totally unused # functions behind them. # This removes some of them. # # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # sound/isa/es1688/es1688_lib.c # 2004/10/27 02:53:01+02:00 perex@suse.cz +1 -2 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # sound/isa/ad1848/ad1848_lib.c # 2004/10/27 02:53:01+02:00 perex@suse.cz +6 -12 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # sound/core/sound.c # 2004/10/27 02:53:00+02:00 perex@suse.cz +0 -1 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # sound/core/seq/instr/ainstr_simple.c # 2004/10/27 02:53:00+02:00 perex@suse.cz +1 -4 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # sound/core/seq/instr/ainstr_iw.c # 2004/10/27 02:53:00+02:00 perex@suse.cz +1 -4 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # sound/core/seq/instr/ainstr_gf1.c # 2004/10/27 02:53:00+02:00 perex@suse.cz +1 -4 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # sound/core/seq/instr/ainstr_fm.c # 2004/10/27 02:53:00+02:00 perex@suse.cz +1 -4 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # sound/core/init.c # 2004/10/27 02:52:59+02:00 perex@suse.cz +0 -3 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # include/sound/es1688.h # 2004/10/27 02:53:01+02:00 perex@suse.cz +0 -2 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # include/sound/core.h # 2004/10/27 02:53:01+02:00 perex@suse.cz +0 -1 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # include/sound/ainstr_iw.h # 2004/10/27 02:53:01+02:00 perex@suse.cz +0 -2 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # include/sound/ainstr_gf1.h # 2004/10/27 02:53:01+02:00 perex@suse.cz +0 -2 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # include/sound/ainstr_fm.h # 2004/10/27 02:53:00+02:00 perex@suse.cz +0 -2 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # include/sound/ad1848.h # 2004/10/27 02:53:00+02:00 perex@suse.cz +0 -5 # [ALSA] remove dead exports # # D:2004/10/27 08:52:59 # C:ALSA Core,Instrument layer,AD1848 driver,ES1688 driver # F:core/init.c:1.49->1.50 # F:core/sound.c:1.66->1.67 # F:core/seq/instr/ainstr_fm.c:1.8->1.9 # F:core/seq/instr/ainstr_gf1.c:1.9->1.10 # F:core/seq/instr/ainstr_iw.c:1.10->1.11 # F:core/seq/instr/ainstr_simple.c:1.8->1.9 # F:include/ad1848.h:1.10->1.11 # F:include/ainstr_fm.h:1.3->1.4 # F:include/ainstr_gf1.h:1.4->1.5 # F:include/ainstr_iw.h:1.4->1.5 # F:include/core.h:1.59->1.60 # F:include/es1688.h:1.6->1.7 # F:isa/ad1848/ad1848_lib.c:1.36->1.37 # F:isa/es1688/es1688_lib.c:1.27->1.28 # L:Alsa currently has tons of dead exports, often with totally unused # L:functions behind them. # L:This removes some of them. # Signed-off-by: Christoph Hellwig # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/10/29 17:15:45+02:00 perex@suse.cz # [ALSA] remove old compatibility code # # USB USX2Y # # # Signed-off-by: Clemens Ladisch # # sound/usb/usx2y/usbusx2yaudio.c # 2004/10/27 02:38:35+02:00 perex@suse.cz +1 -1 # [ALSA] remove old compatibility code # # D:2004/10/27 08:38:35 # C:USB USX2Y # F:usb/usx2y/usbusx2yaudio.c:1.5->1.6 # L: # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/10/29 17:14:41+02:00 perex@suse.cz # [ALSA] fix data type mismatch in sign_invert # # au88x0 driver # the last sign_invert cleanup introduced a data type mismatch # (an unsigned value can never be negative) # # Signed-off-by: Clemens Ladisch # # sound/pci/au88x0/au88x0_eq.c # 2004/10/27 02:31:16+02:00 perex@suse.cz +1 -1 # [ALSA] fix data type mismatch in sign_invert # # D:2004/10/27 08:31:16 # C:au88x0 driver # F:pci/au88x0/au88x0_eq.c:1.7->1.8 # L:the last sign_invert cleanup introduced a data type mismatch # L:(an unsigned value can never be negative) # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/10/29 17:13:39+02:00 perex@suse.cz # [ALSA] au88x0: comment and whitespace cleanup # # au88x0 driver # Remove an obsolete comment and cleanup up some whitespace a bit # # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # sound/pci/au88x0/au88x0.c # 2004/10/26 08:12:31+02:00 perex@suse.cz +5 -8 # [ALSA] au88x0: comment and whitespace cleanup # # D:2004/10/26 14:12:31 # C:au88x0 driver # F:pci/au88x0/au88x0.c:1.15->1.16 # L:Remove an obsolete comment and cleanup up some whitespace a bit # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/10/29 17:12:40+02:00 perex@suse.cz # [ALSA] au88x0: name typo # # au88x0 driver # Fix the spelling of my name # # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # sound/pci/au88x0/au88x0_core.c # 2004/10/26 08:11:34+02:00 perex@suse.cz +1 -1 # [ALSA] au88x0: name typo # # D:2004/10/26 14:11:34 # C:au88x0 driver # F:pci/au88x0/au88x0.c:1.14->1.15 # F:pci/au88x0/au88x0_core.c:1.6->1.7 # L:Fix the spelling of my name # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # sound/pci/au88x0/au88x0.c # 2004/10/26 08:11:34+02:00 perex@suse.cz +1 -1 # [ALSA] au88x0: name typo # # D:2004/10/26 14:11:34 # C:au88x0 driver # F:pci/au88x0/au88x0.c:1.14->1.15 # F:pci/au88x0/au88x0_core.c:1.6->1.7 # L:Fix the spelling of my name # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/10/29 17:11:35+02:00 perex@suse.cz # [ALSA] au88x0: sign_invert cleanup # # au88x0 driver # Remove unecessary ' & 0xffff'ing of the result of sign_invert # # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # sound/pci/au88x0/au88x0_eq.c # 2004/10/26 08:10:54+02:00 perex@suse.cz +15 -15 # [ALSA] au88x0: sign_invert cleanup # # D:2004/10/26 14:10:54 # C:au88x0 driver # F:pci/au88x0/au88x0_eq.c:1.6->1.7 # L:Remove unecessary ' & 0xffff'ing of the result of sign_invert # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/10/29 17:10:29+02:00 perex@suse.cz # [ALSA] au88x0: set-levels cleanup # # au88x0 driver # Cleanup vortex_EqHw_SetLevels and add a bit of documentation # # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # sound/pci/au88x0/au88x0_eq.c # 2004/10/26 08:09:32+02:00 perex@suse.cz +15 -11 # [ALSA] au88x0: set-levels cleanup # # D:2004/10/26 14:09:32 # C:au88x0 driver # F:pci/au88x0/au88x0_eq.c:1.5->1.6 # L:Cleanup vortex_EqHw_SetLevels and add a bit of documentation # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/10/29 17:09:28+02:00 perex@suse.cz # [ALSA] au88x0: fix is-quad oops # # au88x0 driver # Fixes an oops on module removal caused by dereferencing the codec pointer. # This is not the best solution, but it is the easiest and fixes things for # now. # # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # sound/pci/au88x0/au88x0_mixer.c # 2004/10/26 08:08:31+02:00 perex@suse.cz +3 -1 # [ALSA] au88x0: fix is-quad oops # # D:2004/10/26 14:08:31 # C:au88x0 driver # F:pci/au88x0/au88x0.h:1.9->1.10 # F:pci/au88x0/au88x0_mixer.c:1.3->1.4 # L:Fixes an oops on module removal caused by dereferencing the codec pointer. # L:This is not the best solution, but it is the easiest and fixes things for # L:now. # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # sound/pci/au88x0/au88x0.h # 2004/10/26 08:08:31+02:00 perex@suse.cz +4 -1 # [ALSA] au88x0: fix is-quad oops # # D:2004/10/26 14:08:31 # C:au88x0 driver # F:pci/au88x0/au88x0.h:1.9->1.10 # F:pci/au88x0/au88x0_mixer.c:1.3->1.4 # L:Fixes an oops on module removal caused by dereferencing the codec pointer. # L:This is not the best solution, but it is the easiest and fixes things for # L:now. # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/10/29 17:08:26+02:00 perex@suse.cz # [ALSA] au88x0: add resetup dma # # au88x0 driver # Add adbdma_resetup for refreshing the hw page table on pcm start # # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # sound/pci/au88x0/au88x0_pcm.c # 2004/10/26 08:04:51+02:00 perex@suse.cz +3 -1 # [ALSA] au88x0: add resetup dma # # D:2004/10/26 14:04:51 # C:au88x0 driver # F:pci/au88x0/au88x0.h:1.8->1.9 # F:pci/au88x0/au88x0_core.c:1.5->1.6 # F:pci/au88x0/au88x0_pcm.c:1.4->1.5 # L:Add adbdma_resetup for refreshing the hw page table on pcm start # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # sound/pci/au88x0/au88x0_core.c # 2004/10/26 08:04:51+02:00 perex@suse.cz +27 -0 # [ALSA] au88x0: add resetup dma # # D:2004/10/26 14:04:51 # C:au88x0 driver # F:pci/au88x0/au88x0.h:1.8->1.9 # F:pci/au88x0/au88x0_core.c:1.5->1.6 # F:pci/au88x0/au88x0_pcm.c:1.4->1.5 # L:Add adbdma_resetup for refreshing the hw page table on pcm start # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # sound/pci/au88x0/au88x0.h # 2004/10/26 08:04:51+02:00 perex@suse.cz +1 -0 # [ALSA] au88x0: add resetup dma # # D:2004/10/26 14:04:51 # C:au88x0 driver # F:pci/au88x0/au88x0.h:1.8->1.9 # F:pci/au88x0/au88x0_core.c:1.5->1.6 # F:pci/au88x0/au88x0_pcm.c:1.4->1.5 # L:Add adbdma_resetup for refreshing the hw page table on pcm start # Signed-off-by: Jeff Muizelaar # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/10/29 17:07:18+02:00 perex@suse.cz # [ALSA] snd-usb-usx2y - crash fix for OHCI USB-HCDs # # USB USX2Y # Version: 0.8.6 # Work on this started, when rumors spread that OHCI equipped machines would # crash. This was due to me missing two facts: # 1) Ohci has a bigger usb frame number wrap around. # 2) It only supports URB_ISO_ASAP when submitting iso urbs. # These issues are fixed now. # # Signed-off-by: Karsten Wiese # Signed-off-by: Jaroslav Kysela # # sound/usb/usx2y/usbusx2yaudio.c # 2004/10/26 08:03:03+02:00 perex@suse.cz +394 -373 # [ALSA] snd-usb-usx2y - crash fix for OHCI USB-HCDs # # D:2004/10/26 14:03:03 # C:USB USX2Y # F:usb/usx2y/usX2Yhwdep.c:1.2->1.3 # F:usb/usx2y/usbusx2y.c:1.4->1.5 # F:usb/usx2y/usbusx2y.h:1.1->1.2 # F:usb/usx2y/usbusx2yaudio.c:1.4->1.5 # L:Version: 0.8.6 # L:Work on this started, when rumors spread that OHCI equipped machines would # L:crash. This was due to me missing two facts: # L:1) Ohci has a bigger usb frame number wrap around. # L:2) It only supports URB_ISO_ASAP when submitting iso urbs. # L:These issues are fixed now. # Signed-off-by: Karsten Wiese # Signed-off-by: Jaroslav Kysela # # sound/usb/usx2y/usbusx2y.h # 2004/10/26 08:03:03+02:00 perex@suse.cz +33 -12 # [ALSA] snd-usb-usx2y - crash fix for OHCI USB-HCDs # # D:2004/10/26 14:03:03 # C:USB USX2Y # F:usb/usx2y/usX2Yhwdep.c:1.2->1.3 # F:usb/usx2y/usbusx2y.c:1.4->1.5 # F:usb/usx2y/usbusx2y.h:1.1->1.2 # F:usb/usx2y/usbusx2yaudio.c:1.4->1.5 # L:Version: 0.8.6 # L:Work on this started, when rumors spread that OHCI equipped machines would # L:crash. This was due to me missing two facts: # L:1) Ohci has a bigger usb frame number wrap around. # L:2) It only supports URB_ISO_ASAP when submitting iso urbs. # L:These issues are fixed now. # Signed-off-by: Karsten Wiese # Signed-off-by: Jaroslav Kysela # # sound/usb/usx2y/usbusx2y.c # 2004/10/26 08:03:03+02:00 perex@suse.cz +21 -4 # [ALSA] snd-usb-usx2y - crash fix for OHCI USB-HCDs # # D:2004/10/26 14:03:03 # C:USB USX2Y # F:usb/usx2y/usX2Yhwdep.c:1.2->1.3 # F:usb/usx2y/usbusx2y.c:1.4->1.5 # F:usb/usx2y/usbusx2y.h:1.1->1.2 # F:usb/usx2y/usbusx2yaudio.c:1.4->1.5 # L:Version: 0.8.6 # L:Work on this started, when rumors spread that OHCI equipped machines would # L:crash. This was due to me missing two facts: # L:1) Ohci has a bigger usb frame number wrap around. # L:2) It only supports URB_ISO_ASAP when submitting iso urbs. # L:These issues are fixed now. # Signed-off-by: Karsten Wiese # Signed-off-by: Jaroslav Kysela # # sound/usb/usx2y/usX2Yhwdep.c # 2004/10/26 08:03:03+02:00 perex@suse.cz +2 -8 # [ALSA] snd-usb-usx2y - crash fix for OHCI USB-HCDs # # D:2004/10/26 14:03:03 # C:USB USX2Y # F:usb/usx2y/usX2Yhwdep.c:1.2->1.3 # F:usb/usx2y/usbusx2y.c:1.4->1.5 # F:usb/usx2y/usbusx2y.h:1.1->1.2 # F:usb/usx2y/usbusx2yaudio.c:1.4->1.5 # L:Version: 0.8.6 # L:Work on this started, when rumors spread that OHCI equipped machines would # L:crash. This was due to me missing two facts: # L:1) Ohci has a bigger usb frame number wrap around. # L:2) It only supports URB_ISO_ASAP when submitting iso urbs. # L:These issues are fixed now. # Signed-off-by: Karsten Wiese # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/10/29 17:02:54+02:00 perex@suse.cz # [ALSA] rearrange OSS SPARC dependencies # # Sound Core # rearrange the SPARC symbols in the OSS dependencies to # prevent alsa-driver's mod-deps from throwing up # # Signed-off-by: Clemens Ladisch # # sound/Kconfig # 2004/10/26 01:03:18+02:00 perex@suse.cz +1 -1 # [ALSA] rearrange OSS SPARC dependencies # # D:2004/10/26 07:03:18 # C:Sound Core # F:Kconfig:1.8->1.9 # L:rearrange the SPARC symbols in the OSS dependencies to # L:prevent alsa-driver's mod-deps from throwing up # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/10/29 17:01:52+02:00 perex@suse.cz # [ALSA] fix sequencer sleeping in interrupt context # # ALSA sequencer,ALSA<-OSS sequencer # # # Signed-off-by: Clemens Ladisch # # sound/core/seq/seq_clientmgr.c # 2004/10/25 04:43:30+02:00 perex@suse.cz +1 -1 # [ALSA] fix sequencer sleeping in interrupt context # # D:2004/10/25 10:43:30 # C:ALSA sequencer,ALSA<-OSS sequencer # F:core/seq/seq_clientmgr.c:1.38->1.39 # F:core/seq/oss/seq_oss_timer.c:1.7->1.8 # L: # Signed-off-by: Clemens Ladisch # # sound/core/seq/oss/seq_oss_timer.c # 2004/10/25 04:43:30+02:00 perex@suse.cz +1 -1 # [ALSA] fix sequencer sleeping in interrupt context # # D:2004/10/25 10:43:30 # C:ALSA sequencer,ALSA<-OSS sequencer # F:core/seq/seq_clientmgr.c:1.38->1.39 # F:core/seq/oss/seq_oss_timer.c:1.7->1.8 # L: # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/10/29 17:00:31+02:00 perex@suse.cz # [ALSA] use blacklist/whitelist for (non-)audio Bt878 cards # # Documentation,PCI drivers,BT87x driver # Some Bt87x cards use PCI function 1 for MPEG data instead of # audio data, so we blacklist those in the audio driver. # # Further add a whitelist for cards where audio is known to work # (many other cards do not implement the audio connection). # Unknown cards can be enabled manually. # # Signed-off-by: Clemens Ladisch # # sound/pci/bt87x.c # 2004/10/25 03:41:06+02:00 perex@suse.cz +72 -16 # [ALSA] use blacklist/whitelist for (non-)audio Bt878 cards # # D:2004/10/25 09:41:07 # C:Documentation,PCI drivers,BT87x driver # F:Documentation/ALSA-Configuration.txt:1.53->1.54 # F:Documentation/Bt87x.txt:INITIAL->1.1 # F:pci/Kconfig:1.35->1.36 # F:pci/bt87x.c:1.15->1.16 # L:Some Bt87x cards use PCI function 1 for MPEG data instead of # L:audio data, so we blacklist those in the audio driver. # L: # L:Further add a whitelist for cards where audio is known to work # L:(many other cards do not implement the audio connection). # L:Unknown cards can be enabled manually. # Signed-off-by: Clemens Ladisch # # sound/pci/Kconfig # 2004/10/25 03:40:56+02:00 perex@suse.cz +3 -2 # [ALSA] use blacklist/whitelist for (non-)audio Bt878 cards # # D:2004/10/25 09:41:07 # C:Documentation,PCI drivers,BT87x driver # F:Documentation/ALSA-Configuration.txt:1.53->1.54 # F:Documentation/Bt87x.txt:INITIAL->1.1 # F:pci/Kconfig:1.35->1.36 # F:pci/bt87x.c:1.15->1.16 # L:Some Bt87x cards use PCI function 1 for MPEG data instead of # L:audio data, so we blacklist those in the audio driver. # L: # L:Further add a whitelist for cards where audio is known to work # L:(many other cards do not implement the audio connection). # L:Unknown cards can be enabled manually. # Signed-off-by: Clemens Ladisch # # Documentation/sound/alsa/ALSA-Configuration.txt # 2004/10/25 03:41:07+02:00 perex@suse.cz +1 -0 # [ALSA] use blacklist/whitelist for (non-)audio Bt878 cards # # D:2004/10/25 09:41:07 # C:Documentation,PCI drivers,BT87x driver # F:Documentation/ALSA-Configuration.txt:1.53->1.54 # F:Documentation/Bt87x.txt:INITIAL->1.1 # F:pci/Kconfig:1.35->1.36 # F:pci/bt87x.c:1.15->1.16 # L:Some Bt87x cards use PCI function 1 for MPEG data instead of # L:audio data, so we blacklist those in the audio driver. # L: # L:Further add a whitelist for cards where audio is known to work # L:(many other cards do not implement the audio connection). # L:Unknown cards can be enabled manually. # Signed-off-by: Clemens Ladisch # # Documentation/sound/alsa/Bt87x.txt # 2004/10/29 16:45:58+02:00 perex@suse.cz +78 -0 # [ALSA] use blacklist/whitelist for (non-)audio Bt878 cards # # D:2004/10/25 09:41:07 # C:Documentation,PCI drivers,BT87x driver # F:Documentation/ALSA-Configuration.txt:1.53->1.54 # F:Documentation/Bt87x.txt:INITIAL->1.1 # F:pci/Kconfig:1.35->1.36 # F:pci/bt87x.c:1.15->1.16 # L:Some Bt87x cards use PCI function 1 for MPEG data instead of # L:audio data, so we blacklist those in the audio driver. # L: # L:Further add a whitelist for cards where audio is known to work # L:(many other cards do not implement the audio connection). # L:Unknown cards can be enabled manually. # Signed-off-by: Clemens Ladisch # # Documentation/sound/alsa/Bt87x.txt # 2004/10/29 16:45:58+02:00 perex@suse.cz +0 -0 # BitKeeper file /home/perex/bk/linux-sound/work/Documentation/sound/alsa/Bt87x.txt # diff -Nru a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt --- a/Documentation/sound/alsa/ALSA-Configuration.txt 2004-11-17 19:39:27 -08:00 +++ b/Documentation/sound/alsa/ALSA-Configuration.txt 2004-11-17 19:39:27 -08:00 @@ -252,6 +252,7 @@ Module for video cards based on Bt87x chips. digital_rate - Override the default digital rate (Hz) + load_all - Load the driver even if the card model isn't known Module supports up to 8 cards. diff -Nru a/Documentation/sound/alsa/Bt87x.txt b/Documentation/sound/alsa/Bt87x.txt --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/sound/alsa/Bt87x.txt 2004-11-17 19:39:27 -08:00 @@ -0,0 +1,78 @@ +Intro +===== + +You might have noticed that the bt878 grabber cards have actually +_two_ PCI functions: + +$ lspci +[ ... ] +00:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 02) +00:0a.1 Multimedia controller: Brooktree Corporation Bt878 (rev 02) +[ ... ] + +The first does video, it is backward compatible to the bt848. The second +does audio. snd-bt87x is a driver for the second function. It's a sound +driver which can be used for recording sound (and _only_ recording, no +playback). As most TV cards come with a short cable which can be plugged +into your sound card's line-in you probably don't need this driver if all +you want to do is just watching TV... + +Some cards do not bother to connect anything to the audio input pins of +the chip, and some other cards use the audio function to transport MPEG +video data, so it's quite possible that audio recording may not work +with your card. + + +Driver Status +============= + +The driver is now stable. However, it doesn't know about many TV cards, +and it refuses to load for cards it doesn't know. + +If the driver complains ("Unknown TV card found, the audio driver will +not load"), you can specify the load_all=1 option to force the driver to +try to use the audio capture function of your card. If the frequency of +recorded data is not right, try to specify the digital_rate option with +other values than the default 32000 (often it's 44100 or 64000). + +If you have an unknown card, please mail the ID and board name to +, regardless of whether audio capture works or +not, so that future versions of this driver know about your card. + + +Audio modes +=========== + +The chip knows two different modes (digital/analog). snd-bt87x +registers two PCM devices, one for each mode. They cannot be used at +the same time. + + +Digital audio mode +================== + +The first device (hw:X,0) gives you 16 bit stereo sound. The sample +rate depends on the external source which feeds the Bt87x with digital +sound via I2S interface. + + +Analog audio mode (A/D) +======================= + +The second device (hw:X,1) gives you 8 or 16 bit mono sound. Supported +sample rates are between 119466 and 448000 Hz (yes, these numbers are +that high). If you've set the CONFIG_SND_BT87X_OVERCLOCK option, the +maximum sample rate is 1792000 Hz, but audio data becomes unusable +beyond 896000 Hz on my card. + +The chip has three analog inputs. Consequently you'll get a mixer +device to control these. + + +Have fun, + + Clemens + + +Written by Clemens Ladisch +big parts copied from btaudio.txt by Gerd Knorr diff -Nru a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl --- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl 2004-11-17 19:39:27 -08:00 +++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl 2004-11-17 19:39:27 -08:00 @@ -5314,19 +5314,15 @@ - - Here boot_devs is passed but simply ignored since we don't care - the number of parsed parameters. diff -Nru a/Documentation/sound/alsa/OSS-Emulation.txt b/Documentation/sound/alsa/OSS-Emulation.txt --- a/Documentation/sound/alsa/OSS-Emulation.txt 2004-11-17 19:39:27 -08:00 +++ b/Documentation/sound/alsa/OSS-Emulation.txt 2004-11-17 19:39:27 -08:00 @@ -164,16 +164,15 @@ The block and non-block options are used to change the behavior of opening the device file. -As default, ALSA behaves as defined in POSIX, i.e. blocks the file -when it's busy until the device becomes free (unless O_NONBLOCK is -specified). Some applications assume the non-block open behavior, -which are actually implemented in some real OSS drivers. + +As default, ALSA behaves as original OSS drivers, i.e. does not block +the file when it's busy. The -EBUSY error is returned in this case. This blocking behavior can be changed globally via nonblock_open -module option of snd-pcm-oss. For using the non-block mode as default +module option of snd-pcm-oss. For using the blocking mode as default for OSS devices, define like the following: - options snd-pcm-oss nonblock_open=1 + options snd-pcm-oss nonblock_open=0 The partial-frag and no-silence commands have been added recently. Both commands are for optimization use only. The former command diff -Nru a/include/sound/ad1848.h b/include/sound/ad1848.h --- a/include/sound/ad1848.h 2004-11-17 19:39:27 -08:00 +++ b/include/sound/ad1848.h 2004-11-17 19:39:27 -08:00 @@ -157,10 +157,6 @@ /* exported functions */ void snd_ad1848_out(ad1848_t *chip, unsigned char reg, unsigned char value); -void snd_ad1848_dout(ad1848_t *chip, unsigned char reg, unsigned char value); -unsigned char snd_ad1848_in(ad1848_t *chip, unsigned char reg); -void snd_ad1848_mce_up(ad1848_t *chip); -void snd_ad1848_mce_down(ad1848_t *chip); int snd_ad1848_create(snd_card_t * card, unsigned long port, @@ -171,7 +167,6 @@ int snd_ad1848_pcm(ad1848_t * chip, int device, snd_pcm_t **rpcm); const snd_pcm_ops_t *snd_ad1848_get_pcm_ops(int direction); int snd_ad1848_mixer(ad1848_t * chip); -irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs); /* exported mixer stuffs */ enum { AD1848_MIX_SINGLE, AD1848_MIX_DOUBLE, AD1848_MIX_CAPTURE }; diff -Nru a/include/sound/ainstr_fm.h b/include/sound/ainstr_fm.h --- a/include/sound/ainstr_fm.h 2004-11-17 19:39:27 -08:00 +++ b/include/sound/ainstr_fm.h 2004-11-17 19:39:27 -08:00 @@ -122,8 +122,6 @@ #include "seq_instr.h" -extern char *snd_seq_fm_id; - int snd_seq_fm_init(snd_seq_kinstr_ops_t * ops, snd_seq_kinstr_ops_t * next); diff -Nru a/include/sound/ainstr_gf1.h b/include/sound/ainstr_gf1.h --- a/include/sound/ainstr_gf1.h 2004-11-17 19:39:27 -08:00 +++ b/include/sound/ainstr_gf1.h 2004-11-17 19:39:27 -08:00 @@ -203,8 +203,6 @@ #include "seq_instr.h" -extern char *snd_seq_gf1_id; - typedef struct { void *private_data; int (*info)(void *private_data, gf1_info_t *info); diff -Nru a/include/sound/ainstr_iw.h b/include/sound/ainstr_iw.h --- a/include/sound/ainstr_iw.h 2004-11-17 19:39:27 -08:00 +++ b/include/sound/ainstr_iw.h 2004-11-17 19:39:27 -08:00 @@ -351,8 +351,6 @@ #include "seq_instr.h" -extern char *snd_seq_iwffff_id; - typedef struct { void *private_data; int (*info)(void *private_data, iwffff_info_t *info); diff -Nru a/include/sound/ainstr_simple.h b/include/sound/ainstr_simple.h --- a/include/sound/ainstr_simple.h 2004-11-17 19:39:27 -08:00 +++ b/include/sound/ainstr_simple.h 2004-11-17 19:39:27 -08:00 @@ -134,8 +134,6 @@ #include "seq_instr.h" -extern char *snd_seq_simple_id; - typedef struct { void *private_data; int (*info)(void *private_data, simple_instrument_info_t *info); diff -Nru a/include/sound/asound.h b/include/sound/asound.h --- a/include/sound/asound.h 2004-11-17 19:39:27 -08:00 +++ b/include/sound/asound.h 2004-11-17 19:39:27 -08:00 @@ -110,9 +110,10 @@ SNDRV_HWDEP_IFACE_MIXART, /* Digigram miXart cards */ SNDRV_HWDEP_IFACE_USX2Y, /* Tascam US122, US224 & US428 usb */ SNDRV_HWDEP_IFACE_EMUX_WAVETABLE, /* EmuX wavetable */ + SNDRV_HWDEP_IFACE_BLUETOOTH, /* Bluetooth audio */ /* Don't forget to change the following: */ - SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_EMUX_WAVETABLE, + SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_BLUETOOTH, }; struct sndrv_hwdep_info { diff -Nru a/include/sound/core.h b/include/sound/core.h --- a/include/sound/core.h 2004-11-17 19:39:27 -08:00 +++ b/include/sound/core.h 2004-11-17 19:39:27 -08:00 @@ -312,7 +312,6 @@ /* init.c */ -extern int snd_cards_count; extern unsigned int snd_cards_lock; extern snd_card_t *snd_cards[SNDRV_CARDS]; extern rwlock_t snd_card_rwlock; diff -Nru a/include/sound/emu10k1.h b/include/sound/emu10k1.h --- a/include/sound/emu10k1.h 2004-11-17 19:39:27 -08:00 +++ b/include/sound/emu10k1.h 2004-11-17 19:39:27 -08:00 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -1000,6 +1001,8 @@ snd_pcm_substream_t *pcm_capture_mic_substream; snd_pcm_substream_t *pcm_capture_efx_substream; + snd_timer_t *timer; + emu10k1_midi_t midi; emu10k1_midi_t midi2; /* for audigy */ @@ -1019,6 +1022,7 @@ int snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm); int snd_emu10k1_fx8010_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm); int snd_emu10k1_mixer(emu10k1_t * emu); +int snd_emu10k1_timer(emu10k1_t * emu, int device); int snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep); irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs); @@ -1334,7 +1338,7 @@ char name[128]; DECLARE_BITMAP(gpr_valid, 0x200); /* bitmask of valid initializers */ - unsigned int gpr_map[0x200]; /* initializers */ + u_int32_t __user *gpr_map; /* initializers */ unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */ emu10k1_fx8010_control_gpr_t __user *gpr_add_controls; /* GPR controls to add/replace */ @@ -1347,11 +1351,11 @@ emu10k1_fx8010_control_gpr_t __user *gpr_list_controls; /* listed GPR controls */ DECLARE_BITMAP(tram_valid, 0x100); /* bitmask of valid initializers */ - unsigned int tram_data_map[0x100]; /* data initializers */ - unsigned int tram_addr_map[0x100]; /* map initializers */ + u_int32_t __user *tram_data_map; /* data initializers */ + u_int32_t __user *tram_addr_map; /* map initializers */ DECLARE_BITMAP(code_valid, 1024); /* bitmask of valid instructions */ - unsigned int code[1024][2]; /* one instruction - 64 bits */ + u_int32_t __user *code; /* one instruction - 64 bits */ } emu10k1_fx8010_code_t; typedef struct { diff -Nru a/include/sound/es1688.h b/include/sound/es1688.h --- a/include/sound/es1688.h 2004-11-17 19:39:27 -08:00 +++ b/include/sound/es1688.h 2004-11-17 19:39:27 -08:00 @@ -110,8 +110,6 @@ void snd_es1688_mixer_write(es1688_t *chip, unsigned char reg, unsigned char data); unsigned char snd_es1688_mixer_read(es1688_t *chip, unsigned char reg); -irqreturn_t snd_es1688_interrupt(int irq, void *dev_id, struct pt_regs *regs); - int snd_es1688_create(snd_card_t * card, unsigned long port, unsigned long mpu_port, diff -Nru a/include/sound/version.h b/include/sound/version.h --- a/include/sound/version.h 2004-11-17 19:39:27 -08:00 +++ b/include/sound/version.h 2004-11-17 19:39:27 -08:00 @@ -1,3 +1,3 @@ /* include/version.h. Generated by configure. */ -#define CONFIG_SND_VERSION "1.0.6" -#define CONFIG_SND_DATE " (Sun Aug 15 07:17:53 2004 UTC)" +#define CONFIG_SND_VERSION "1.0.7" +#define CONFIG_SND_DATE " (Thu Nov 11 10:36:46 2004 UTC)" diff -Nru a/sound/Kconfig b/sound/Kconfig --- a/sound/Kconfig 2004-11-17 19:39:27 -08:00 +++ b/sound/Kconfig 2004-11-17 19:39:27 -08:00 @@ -70,7 +70,7 @@ endmenu menu "Open Sound System" - depends on SOUND!=n && (BROKEN || !(SPARC32 || SPARC64)) + depends on SOUND!=n && (BROKEN || (!SPARC32 && !SPARC64)) config SOUND_PRIME tristate "Open Sound System (DEPRECATED)" diff -Nru a/sound/core/info.c b/sound/core/info.c --- a/sound/core/info.c 2004-11-17 19:39:27 -08:00 +++ b/sound/core/info.c 2004-11-17 19:39:27 -08:00 @@ -20,18 +20,14 @@ */ #include -#include #include #include #include #include -#include -#include - #include -#include #include #include +#include #include #include #include @@ -962,18 +958,10 @@ static void snd_info_version_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer) { - static char *kernel_version = system_utsname.release; - snd_iprintf(buffer, - "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n" - "Compiled on " __DATE__ " for kernel %s" -#ifdef CONFIG_SMP - " (SMP)" -#endif -#ifdef MODVERSIONS - " with versioned symbols" -#endif - ".\n", kernel_version); + "Advanced Linux Sound Architecture Driver Version " + CONFIG_SND_VERSION CONFIG_SND_DATE ".\n" + ); } static int __init snd_info_version_init(void) diff -Nru a/sound/core/init.c b/sound/core/init.c --- a/sound/core/init.c 2004-11-17 19:39:27 -08:00 +++ b/sound/core/init.c 2004-11-17 19:39:27 -08:00 @@ -37,7 +37,6 @@ struct snd_shutdown_f_ops *next; }; -int snd_cards_count = 0; unsigned int snd_cards_lock = 0; /* locked for registering/using */ snd_card_t *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL}; rwlock_t snd_card_rwlock = RW_LOCK_UNLOCKED; @@ -251,7 +250,6 @@ return -EINVAL; write_lock(&snd_card_rwlock); snd_cards[card->number] = NULL; - snd_cards_count--; write_unlock(&snd_card_rwlock); #ifdef CONFIG_PM @@ -441,7 +439,6 @@ if (card->id[0] == '\0') choose_default_id(card); snd_cards[card->number] = card; - snd_cards_count++; write_unlock(&snd_card_rwlock); if ((err = snd_info_card_register(card)) < 0) { snd_printd("unable to create card info\n"); diff -Nru a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c --- a/sound/core/oss/pcm_oss.c 2004-11-17 19:39:27 -08:00 +++ b/sound/core/oss/pcm_oss.c 2004-11-17 19:39:27 -08:00 @@ -46,7 +46,7 @@ static int dsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0}; static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; -static int nonblock_open; +static int nonblock_open = 1; MODULE_AUTHOR("Jaroslav Kysela , Abramo Bagnara "); MODULE_DESCRIPTION("PCM OSS emulation for ALSA."); diff -Nru a/sound/core/seq/instr/ainstr_fm.c b/sound/core/seq/instr/ainstr_fm.c --- a/sound/core/seq/instr/ainstr_fm.c 2004-11-17 19:39:27 -08:00 +++ b/sound/core/seq/instr/ainstr_fm.c 2004-11-17 19:39:27 -08:00 @@ -30,8 +30,6 @@ MODULE_DESCRIPTION("Advanced Linux Sound Architecture FM Instrument support."); MODULE_LICENSE("GPL"); -char *snd_seq_fm_id = SNDRV_SEQ_INSTR_ID_OPL2_3; - static int snd_seq_fm_put(void *private_data, snd_seq_kinstr_t *instr, char __user *instr_data, long len, int atomic, int cmd) { @@ -129,7 +127,7 @@ memset(ops, 0, sizeof(*ops)); // ops->private_data = private_data; ops->add_len = sizeof(fm_instrument_t); - ops->instr_type = snd_seq_fm_id; + ops->instr_type = SNDRV_SEQ_INSTR_ID_OPL2_3; ops->put = snd_seq_fm_put; ops->get = snd_seq_fm_get; ops->get_size = snd_seq_fm_get_size; @@ -155,5 +153,4 @@ module_init(alsa_ainstr_fm_init) module_exit(alsa_ainstr_fm_exit) -EXPORT_SYMBOL(snd_seq_fm_id); EXPORT_SYMBOL(snd_seq_fm_init); diff -Nru a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c --- a/sound/core/seq/instr/ainstr_gf1.c 2004-11-17 19:39:27 -08:00 +++ b/sound/core/seq/instr/ainstr_gf1.c 2004-11-17 19:39:27 -08:00 @@ -31,8 +31,6 @@ MODULE_DESCRIPTION("Advanced Linux Sound Architecture GF1 (GUS) Patch support."); MODULE_LICENSE("GPL"); -char *snd_seq_gf1_id = SNDRV_SEQ_INSTR_ID_GUS_PATCH; - static unsigned int snd_seq_gf1_size(unsigned int size, unsigned int format) { unsigned int result = size; @@ -331,7 +329,7 @@ ops->private_data = private_data; ops->kops.private_data = ops; ops->kops.add_len = sizeof(gf1_instrument_t); - ops->kops.instr_type = snd_seq_gf1_id; + ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_GUS_PATCH; ops->kops.put = snd_seq_gf1_put; ops->kops.get = snd_seq_gf1_get; ops->kops.get_size = snd_seq_gf1_get_size; @@ -357,5 +355,4 @@ module_init(alsa_ainstr_gf1_init) module_exit(alsa_ainstr_gf1_exit) -EXPORT_SYMBOL(snd_seq_gf1_id); EXPORT_SYMBOL(snd_seq_gf1_init); diff -Nru a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c --- a/sound/core/seq/instr/ainstr_iw.c 2004-11-17 19:39:27 -08:00 +++ b/sound/core/seq/instr/ainstr_iw.c 2004-11-17 19:39:27 -08:00 @@ -31,8 +31,6 @@ MODULE_DESCRIPTION("Advanced Linux Sound Architecture IWFFFF support."); MODULE_LICENSE("GPL"); -char *snd_seq_iwffff_id = SNDRV_SEQ_INSTR_ID_INTERWAVE; - static unsigned int snd_seq_iwffff_size(unsigned int size, unsigned int format) { unsigned int result = size; @@ -595,7 +593,7 @@ ops->private_data = private_data; ops->kops.private_data = ops; ops->kops.add_len = sizeof(iwffff_instrument_t); - ops->kops.instr_type = snd_seq_iwffff_id; + ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_INTERWAVE; ops->kops.put = snd_seq_iwffff_put; ops->kops.get = snd_seq_iwffff_get; ops->kops.get_size = snd_seq_iwffff_get_size; @@ -621,5 +619,4 @@ module_init(alsa_ainstr_iw_init) module_exit(alsa_ainstr_iw_exit) -EXPORT_SYMBOL(snd_seq_iwffff_id); EXPORT_SYMBOL(snd_seq_iwffff_init); diff -Nru a/sound/core/seq/instr/ainstr_simple.c b/sound/core/seq/instr/ainstr_simple.c --- a/sound/core/seq/instr/ainstr_simple.c 2004-11-17 19:39:27 -08:00 +++ b/sound/core/seq/instr/ainstr_simple.c 2004-11-17 19:39:27 -08:00 @@ -31,8 +31,6 @@ MODULE_DESCRIPTION("Advanced Linux Sound Architecture Simple Instrument support."); MODULE_LICENSE("GPL"); -char *snd_seq_simple_id = SNDRV_SEQ_INSTR_ID_SIMPLE; - static unsigned int snd_seq_simple_size(unsigned int size, unsigned int format) { unsigned int result = size; @@ -188,7 +186,7 @@ ops->private_data = private_data; ops->kops.private_data = ops; ops->kops.add_len = sizeof(simple_instrument_t); - ops->kops.instr_type = snd_seq_simple_id; + ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_SIMPLE; ops->kops.put = snd_seq_simple_put; ops->kops.get = snd_seq_simple_get; ops->kops.get_size = snd_seq_simple_get_size; @@ -214,5 +212,4 @@ module_init(alsa_ainstr_simple_init) module_exit(alsa_ainstr_simple_exit) -EXPORT_SYMBOL(snd_seq_simple_id); EXPORT_SYMBOL(snd_seq_simple_init); diff -Nru a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c --- a/sound/core/seq/oss/seq_oss_timer.c 2004-11-17 19:39:27 -08:00 +++ b/sound/core/seq/oss/seq_oss_timer.c 2004-11-17 19:39:27 -08:00 @@ -149,7 +149,7 @@ ev.queue = dp->queue; ev.data.queue.queue = dp->queue; ev.data.queue.param.value = value; - return snd_seq_kernel_client_dispatch(dp->cseq, &ev, 0, 0); + return snd_seq_kernel_client_dispatch(dp->cseq, &ev, 1, 0); } /* diff -Nru a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c --- a/sound/core/seq/seq_clientmgr.c 2004-11-17 19:39:27 -08:00 +++ b/sound/core/seq/seq_clientmgr.c 2004-11-17 19:39:27 -08:00 @@ -904,7 +904,7 @@ return -ENXIO; /* queue is not allocated */ /* allocate an event cell */ - err = snd_seq_event_dup(client->pool, event, &cell, !blocking && !atomic, file); + err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic, file); if (err < 0) return err; diff -Nru a/sound/core/sound.c b/sound/core/sound.c --- a/sound/core/sound.c 2004-11-17 19:39:27 -08:00 +++ b/sound/core/sound.c 2004-11-17 19:39:27 -08:00 @@ -411,7 +411,6 @@ EXPORT_SYMBOL(copy_to_user_fromio); EXPORT_SYMBOL(copy_from_user_toio); /* init.c */ -EXPORT_SYMBOL(snd_cards_count); EXPORT_SYMBOL(snd_cards); #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) EXPORT_SYMBOL(snd_mixer_oss_notify_callback); diff -Nru a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c --- a/sound/isa/ad1848/ad1848_lib.c 2004-11-17 19:39:27 -08:00 +++ b/sound/isa/ad1848/ad1848_lib.c 2004-11-17 19:39:27 -08:00 @@ -119,9 +119,8 @@ #endif } -void snd_ad1848_dout(ad1848_t *chip, - unsigned char reg, - unsigned char value) +static void snd_ad1848_dout(ad1848_t *chip, + unsigned char reg, unsigned char value) { int timeout; @@ -132,7 +131,7 @@ mb(); } -unsigned char snd_ad1848_in(ad1848_t *chip, unsigned char reg) +static unsigned char snd_ad1848_in(ad1848_t *chip, unsigned char reg) { int timeout; @@ -177,7 +176,7 @@ * AD1848 detection / MCE routines */ -void snd_ad1848_mce_up(ad1848_t *chip) +static void snd_ad1848_mce_up(ad1848_t *chip) { unsigned long flags; int timeout; @@ -198,7 +197,7 @@ spin_unlock_irqrestore(&chip->reg_lock, flags); } -void snd_ad1848_mce_down(ad1848_t *chip) +static void snd_ad1848_mce_down(ad1848_t *chip) { unsigned long flags; int timeout; @@ -584,7 +583,7 @@ return 0; } -irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs) { ad1848_t *chip = dev_id; @@ -1264,12 +1263,7 @@ return 0; } -EXPORT_SYMBOL(snd_ad1848_in); EXPORT_SYMBOL(snd_ad1848_out); -EXPORT_SYMBOL(snd_ad1848_dout); -EXPORT_SYMBOL(snd_ad1848_mce_up); -EXPORT_SYMBOL(snd_ad1848_mce_down); -EXPORT_SYMBOL(snd_ad1848_interrupt); EXPORT_SYMBOL(snd_ad1848_create); EXPORT_SYMBOL(snd_ad1848_pcm); EXPORT_SYMBOL(snd_ad1848_get_pcm_ops); diff -Nru a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c --- a/sound/isa/cs423x/cs4231_lib.c 2004-11-17 19:39:27 -08:00 +++ b/sound/isa/cs423x/cs4231_lib.c 2004-11-17 19:39:27 -08:00 @@ -356,7 +356,6 @@ { unsigned long flags; int timeout; - signed long time; snd_cs4231_busy_wait(chip); #if 0 @@ -390,34 +389,26 @@ #if 0 printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies); #endif - timeout = HZ / 4 / 2; - time = 2; + /* in 10 ms increments, check condition, up to 250 ms */ + timeout = 25; while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) { - set_current_state(TASK_INTERRUPTIBLE); - time = schedule_timeout(time); - if (time > 0) - continue; - time = 2; if (--timeout < 0) { snd_printk("mce_down - auto calibration time out (2)\n"); return; } + msleep(10); } #if 0 printk("(3) jiffies = %li\n", jiffies); #endif - timeout = HZ / 10 / 2; - time = 2; + /* in 10 ms increments, check condition, up to 100 ms */ + timeout = 10; while (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) { - set_current_state(TASK_INTERRUPTIBLE); - time = schedule_timeout(time); - if (time > 0) - continue; - time = 2; if (--timeout < 0) { snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n"); return; } + msleep(10); } #if 0 printk("(4) jiffies = %li\n", jiffies); diff -Nru a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c --- a/sound/isa/es1688/es1688_lib.c 2004-11-17 19:39:27 -08:00 +++ b/sound/isa/es1688/es1688_lib.c 2004-11-17 19:39:27 -08:00 @@ -479,7 +479,7 @@ return snd_es1688_trigger(chip, cmd, 0x0f); } -irqreturn_t snd_es1688_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t snd_es1688_interrupt(int irq, void *dev_id, struct pt_regs *regs) { es1688_t *chip = dev_id; @@ -1042,7 +1042,6 @@ EXPORT_SYMBOL(snd_es1688_mixer_write); EXPORT_SYMBOL(snd_es1688_mixer_read); -EXPORT_SYMBOL(snd_es1688_interrupt); EXPORT_SYMBOL(snd_es1688_create); EXPORT_SYMBOL(snd_es1688_pcm); EXPORT_SYMBOL(snd_es1688_mixer); diff -Nru a/sound/isa/gus/gus_sample.c b/sound/isa/gus/gus_sample.c --- a/sound/isa/gus/gus_sample.c 2004-11-17 19:39:27 -08:00 +++ b/sound/isa/gus/gus_sample.c 2004-11-17 19:39:27 -08:00 @@ -42,7 +42,7 @@ instr = snd_seq_instr_find(gus->gf1.ilist, &v->instr, 0, 1); if (instr != NULL) { if (instr->ops) { - if (instr->ops->instr_type == snd_seq_simple_id) + if (!strcmp(instr->ops->instr_type, SNDRV_SEQ_INSTR_ID_SIMPLE)) snd_gf1_simple_init(v); } snd_seq_instr_free_use(gus->gf1.ilist, instr); diff -Nru a/sound/pci/Kconfig b/sound/pci/Kconfig --- a/sound/pci/Kconfig 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/Kconfig 2004-11-17 19:39:27 -08:00 @@ -106,8 +106,9 @@ depends on SND select SND_PCM help - Say Y here to include support for recording audio from TV - cards based on Brooktree Bt878/Bt879 chips. + If you want to record audio from TV cards based on + Brooktree Bt878/Bt879 chips, say Y here and read + . To compile this driver as a module, choose M here: the module will be called snd-bt87x. diff -Nru a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c --- a/sound/pci/au88x0/au88x0.c 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/au88x0/au88x0.c 2004-11-17 19:39:27 -08:00 @@ -4,7 +4,7 @@ * * This driver is the result of the OpenVortex Project from Savannah * (savannah.nongnu.org/projects/openvortex). I would like to thank - * the developers of OpenVortex, Jeff Muizelar and Kester Maddock, from + * the developers of OpenVortex, Jeff Muizelaar and Kester Maddock, from * whom i got plenty of help, and their codebase was invaluable. * Thanks to the ALSA developers, they helped a lot working out * the ALSA part. @@ -170,9 +170,8 @@ if ((err = pci_request_regions(pci, CARD_NAME_SHORT)) != 0) goto regions_out; - chip->mmio = - ioremap_nocache(pci_resource_start(pci, 0), - pci_resource_len(pci, 0)); + chip->mmio = ioremap_nocache(pci_resource_start(pci, 0), + pci_resource_len(pci, 0)); if (!chip->mmio) { printk(KERN_ERR "MMIO area remap failed.\n"); err = -ENOMEM; @@ -187,10 +186,9 @@ goto core_out; } - if ((err = - request_irq(pci->irq, vortex_interrupt, - SA_INTERRUPT | SA_SHIRQ, CARD_NAME_SHORT, - (void *)chip)) != 0) { + if ((err = request_irq(pci->irq, vortex_interrupt, + SA_INTERRUPT | SA_SHIRQ, CARD_NAME_SHORT, + chip)) != 0) { printk(KERN_ERR "cannot grab irq\n"); goto irq_out; } @@ -214,7 +212,6 @@ irq_out: vortex_core_shutdown(chip); core_out: - //FIXME: the type of chip->mmio might need to be changed?? iounmap(chip->mmio); ioremap_out: pci_release_regions(chip->pci_dev); diff -Nru a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h --- a/sound/pci/au88x0/au88x0.h 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/au88x0/au88x0.h 2004-11-17 19:39:27 -08:00 @@ -80,7 +80,8 @@ #define VORTEX_RESOURCE_LAST 0x00000005 /* Check for SDAC bit in "Extended audio ID" AC97 register */ -#define VORTEX_IS_QUAD(x) ((x->codec == NULL) ? 0 : (x->codec->ext_id&0x80)) +//#define VORTEX_IS_QUAD(x) (((x)->codec == NULL) ? 0 : ((x)->codec->ext_id&0x80)) +#define VORTEX_IS_QUAD(x) ((x)->isquad) /* Check if chip has bug. */ #define IS_BAD_CHIP(x) (\ (x->rev == 0xfe && x->device == PCI_DEVICE_ID_AUREAL_VORTEX_2) || \ @@ -164,6 +165,8 @@ int xt_mode; /* 1: speakers, 0:headphones. */ #endif + int isquad; /* cache of extended ID codec flag. */ + /* Gameport stuff. */ struct gameport *gameport; @@ -208,6 +211,7 @@ static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma); static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma); static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma); +static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma); #ifndef CHIP_AU8810 static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma); diff -Nru a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c --- a/sound/pci/au88x0/au88x0_core.c 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/au88x0/au88x0_core.c 2004-11-17 19:39:27 -08:00 @@ -21,7 +21,7 @@ These functions are mainly the result of translations made from the original disassembly of the au88x0 binary drivers, written by Aureal before they went down. - Many thanks to the Jeff Muizelar, Kester Maddock, and whoever + Many thanks to the Jeff Muizelaar, Kester Maddock, and whoever contributed to the OpenVortex project. The author of this file, put the few available pieces together and translated the rest of the riddle (Mix, Src and connection stuff). @@ -1221,6 +1221,33 @@ adbdma, dma->period_virt, dma->period_real, delta); return delta; +} + + +static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) { + stream_t *dma = &vortex->dma_adb[adbdma]; + int p, pp, i; + + /* refresh hw page table */ + for (i=0 ; i < 4 && i < dma->nr_periods; i++) { + /* p: audio buffer page index */ + p = dma->period_virt + i; + if (p >= dma->nr_periods) + p -= dma->nr_periods; + /* pp: hardware DMA page index. */ + pp = dma->period_real + i; + if (dma->nr_periods < 4) { + if (pp >= dma->nr_periods) + pp -= dma->nr_periods; + } + else { + if (pp >= 4) + pp -= 4; + } + hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p)); + /* Force write thru cache. */ + hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2)); + } } static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma) diff -Nru a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c --- a/sound/pci/au88x0/au88x0_eq.c 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/au88x0/au88x0_eq.c 2004-11-17 19:39:27 -08:00 @@ -45,6 +45,8 @@ #define VORTEX_EQ_SOURCE (VORTEX_EQ_BASE + 0x430) #define VORTEX_EQ_CTRL (VORTEX_EQ_BASE + 0x440) +#define VORTEX_BAND_COEFF_SIZE 0x30 + /* CEqHw.s */ static void vortex_EqHw_SetTimeConsts(vortex_t * vortex, u16 gain, u16 level) { @@ -52,10 +54,10 @@ hwwrite(vortex->mmio, 0x2b3c8, level); } -static inline short sign_invert(short a) +static inline u16 sign_invert(u16 a) { /* -(-32768) -> -32768 so we do -(-32768) -> 32767 to make the result positive */ - if (a == -32768) + if (a == (u16)-32768) return 32767; else return -a; @@ -71,13 +73,13 @@ hwwrite(vortex->mmio, 0x2b004 + n * 0x30, coefs[i + 1]); if (eqhw->this08 == 0) { - hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2] & 0xffff); - hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3] & 0xffff); - hwwrite(vortex->mmio, 0x2b010 + n * 0x30, coefs[i + 4] & 0xffff); + hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2]); + hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3]); + hwwrite(vortex->mmio, 0x2b010 + n * 0x30, coefs[i + 4]); } else { - hwwrite(vortex->mmio, 0x2b008 + n * 0x30, sign_invert(coefs[2 + i]) & 0xffff); - hwwrite(vortex->mmio, 0x2b00c + n * 0x30, sign_invert(coefs[3 + i]) & 0xffff); - hwwrite(vortex->mmio, 0x2b010 + n * 0x30, sign_invert(coefs[4 + i]) & 0xffff); + hwwrite(vortex->mmio, 0x2b008 + n * 0x30, sign_invert(coefs[2 + i])); + hwwrite(vortex->mmio, 0x2b00c + n * 0x30, sign_invert(coefs[3 + i])); + hwwrite(vortex->mmio, 0x2b010 + n * 0x30, sign_invert(coefs[4 + i])); } i += 5; } @@ -93,13 +95,13 @@ hwwrite(vortex->mmio, 0x2b1e4 + n * 0x30, coefs[1 + i]); if (eqhw->this08 == 0) { - hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i] & 0xffff); - hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i] & 0xffff); - hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, coefs[4 + i] & 0xffff); + hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i]); + hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i]); + hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, coefs[4 + i]); } else { - hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, sign_invert(coefs[2 + i]) & 0xffff); - hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, sign_invert(coefs[3 + i]) & 0xffff); - hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, sign_invert(coefs[4 + i]) & 0xffff); + hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, sign_invert(coefs[2 + i])); + hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, sign_invert(coefs[3 + i])); + hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, sign_invert(coefs[4 + i])); } i += 5; } @@ -176,8 +178,8 @@ hwwrite(vortex->mmio, 0x2b3d4, a); hwwrite(vortex->mmio, 0x2b3ec, b); } else { - hwwrite(vortex->mmio, 0x2b3d4, sign_invert(a) & 0xffff); - hwwrite(vortex->mmio, 0x2b3ec, sign_invert(b) & 0xffff); + hwwrite(vortex->mmio, 0x2b3d4, sign_invert(a)); + hwwrite(vortex->mmio, 0x2b3ec, sign_invert(b)); } } @@ -319,25 +321,27 @@ #endif /* EQ band levels settings */ -static void vortex_EqHw_SetLevels(vortex_t * vortex, u16 a[]) +static void vortex_EqHw_SetLevels(vortex_t * vortex, u16 peaks[]) { eqhw_t *eqhw = &(vortex->eq.this04); - int ebx; + int i; - for (ebx = 0; ebx < eqhw->this04; ebx++) { - hwwrite(vortex->mmio, 0x2b024 + ebx * 0x30, a[ebx]); + /* set left peaks */ + for (i = 0; i < eqhw->this04; i++) { + hwwrite(vortex->mmio, 0x2b024 + i * VORTEX_BAND_COEFF_SIZE, peaks[i]); } - hwwrite(vortex->mmio, 0x2b3cc, a[eqhw->this04]); - hwwrite(vortex->mmio, 0x2b3d8, a[eqhw->this04 + 1]); + hwwrite(vortex->mmio, 0x2b3cc, peaks[eqhw->this04]); + hwwrite(vortex->mmio, 0x2b3d8, peaks[eqhw->this04 + 1]); - for (ebx = 0; ebx < eqhw->this04; ebx++) { - hwwrite(vortex->mmio, 0x2b204 + ebx * 0x30, - a[ebx + (eqhw->this04 + 2)]); + /* set right peaks */ + for (i = 0; i < eqhw->this04; i++) { + hwwrite(vortex->mmio, 0x2b204 + i * VORTEX_BAND_COEFF_SIZE, + peaks[i + (eqhw->this04 + 2)]); } - hwwrite(vortex->mmio, 0x2b3e4, a[2 + (eqhw->this04 * 2)]); - hwwrite(vortex->mmio, 0x2b3f0, a[3 + (eqhw->this04 * 2)]); + hwwrite(vortex->mmio, 0x2b3e4, peaks[2 + (eqhw->this04 * 2)]); + hwwrite(vortex->mmio, 0x2b3f0, peaks[3 + (eqhw->this04 * 2)]); } #if 0 diff -Nru a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c --- a/sound/pci/au88x0/au88x0_mixer.c 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/au88x0/au88x0_mixer.c 2004-11-17 19:39:27 -08:00 @@ -26,5 +26,7 @@ memset(&ac97, 0, sizeof(ac97)); // Intialize AC97 codec stuff. ac97.private_data = vortex; - return snd_ac97_mixer(pbus, &ac97, &vortex->codec); + err = snd_ac97_mixer(pbus, &ac97, &vortex->codec); + vortex->isquad = ((vortex->codec == NULL) ? 0 : (vortex->codec->ext_id&0x80)); + return err; } diff -Nru a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c --- a/sound/pci/au88x0/au88x0_pcm.c 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/au88x0/au88x0_pcm.c 2004-11-17 19:39:27 -08:00 @@ -313,8 +313,10 @@ // do something to start the PCM engine //printk(KERN_INFO "vortex: start %d\n", dma); stream->fifo_enabled = 1; - if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) + if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { + vortex_adbdma_resetup(chip, dma); vortex_adbdma_startfifo(chip, dma); + } #ifndef CHIP_AU8810 else { printk(KERN_INFO "vortex: wt start %d\n", dma); diff -Nru a/sound/pci/bt87x.c b/sound/pci/bt87x.c --- a/sound/pci/bt87x.c 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/bt87x.c 2004-11-17 19:39:27 -08:00 @@ -45,6 +45,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int digital_rate[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* digital input rate */ +static int load_all; /* allow to load the non-whitelisted cards */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Bt87x soundcard"); @@ -54,6 +55,8 @@ MODULE_PARM_DESC(enable, "Enable Bt87x soundcard"); module_param_array(digital_rate, int, NULL, 0444); MODULE_PARM_DESC(digital_rate, "Digital input rate for Bt87x soundcard"); +module_param(load_all, bool, 0444); +MODULE_PARM_DESC(load_all, "Allow to load the non-whitelisted cards"); #ifndef PCI_VENDOR_ID_BROOKTREE @@ -173,7 +176,11 @@ unsigned int lines; u32 reg_control; + u32 interrupt_mask; + int current_line; + + int pci_parity_errors; }; enum { DEVICE_DIGITAL, DEVICE_ANALOG }; @@ -246,33 +253,53 @@ } } +static void snd_bt87x_pci_error(bt87x_t *chip, unsigned int status) +{ + u16 pci_status; + + pci_read_config_word(chip->pci, PCI_STATUS, &pci_status); + pci_status &= PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT | + PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT | + PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY; + pci_write_config_word(chip->pci, PCI_STATUS, pci_status); + if (pci_status != PCI_STATUS_DETECTED_PARITY) + snd_printk(KERN_ERR "Aieee - PCI error! status %#08x, PCI status %#04x\n", + status & ERROR_INTERRUPTS, pci_status); + else { + snd_printk(KERN_ERR "Aieee - PCI parity error detected!\n"); + /* error 'handling' similar to aic7xxx_pci.c: */ + chip->pci_parity_errors++; + if (chip->pci_parity_errors > 20) { + snd_printk(KERN_ERR "Too many PCI parity errors observed.\n"); + snd_printk(KERN_ERR "Some device on this bus is generating bad parity.\n"); + snd_printk(KERN_ERR "This is an error *observed by*, not *generated by*, this card.\n"); + snd_printk(KERN_ERR "PCI parity error checking has been disabled.\n"); + chip->interrupt_mask &= ~(INT_PPERR | INT_RIPERR); + snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask); + } + } +} + static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id, struct pt_regs *regs) { bt87x_t *chip = dev_id; - unsigned int status; + unsigned int status, irq_status; status = snd_bt87x_readl(chip, REG_INT_STAT); - if (!(status & MY_INTERRUPTS)) + irq_status = status & chip->interrupt_mask; + if (!irq_status) return IRQ_NONE; - snd_bt87x_writel(chip, REG_INT_STAT, status & MY_INTERRUPTS); + snd_bt87x_writel(chip, REG_INT_STAT, irq_status); - if (status & ERROR_INTERRUPTS) { - if (status & (INT_FBUS | INT_FTRGT)) + if (irq_status & ERROR_INTERRUPTS) { + if (irq_status & (INT_FBUS | INT_FTRGT)) snd_printk(KERN_WARNING "FIFO overrun, status %#08x\n", status); - if (status & INT_OCERR) + if (irq_status & INT_OCERR) snd_printk(KERN_ERR "internal RISC error, status %#08x\n", status); - if (status & (INT_PPERR | INT_RIPERR | INT_PABORT)) { - u16 pci_status; - pci_read_config_word(chip->pci, PCI_STATUS, &pci_status); - pci_write_config_word(chip->pci, PCI_STATUS, pci_status & - (PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT | - PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT | - PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY)); - snd_printk(KERN_ERR "Aieee - PCI error! status %#08x, PCI status %#04x\n", - status, pci_status); - } + if (irq_status & (INT_PPERR | INT_RIPERR | INT_PABORT)) + snd_bt87x_pci_error(chip, irq_status); } - if ((status & INT_RISCI) && (chip->reg_control & CTL_ACAP_EN)) { + if ((irq_status & INT_RISCI) && (chip->reg_control & CTL_ACAP_EN)) { int current_block, irq_block; /* assume that exactly one line has been recorded */ @@ -458,7 +485,7 @@ snd_bt87x_writel(chip, REG_RISC_STRT_ADD, chip->dma_risc.addr); snd_bt87x_writel(chip, REG_PACKET_LEN, chip->line_bytes | (chip->lines << 16)); - snd_bt87x_writel(chip, REG_INT_MASK, MY_INTERRUPTS); + snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask); snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control); spin_unlock(&chip->reg_lock); return 0; @@ -713,6 +740,7 @@ } chip->reg_control = CTL_DA_ES2 | CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT); + chip->interrupt_mask = MY_INTERRUPTS; snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control); snd_bt87x_writel(chip, REG_INT_MASK, 0); snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS); @@ -737,13 +765,73 @@ return 0; } +#define BT_DEVICE(chip, subvend, subdev, rate) \ + { .vendor = PCI_VENDOR_ID_BROOKTREE, \ + .device = PCI_DEVICE_ID_BROOKTREE_##chip, \ + .subvendor = subvend, .subdevice = subdev, \ + .driver_data = rate } + +/* driver_data is the default digital_rate value for that device */ +static struct pci_device_id snd_bt87x_ids[] = { + BT_DEVICE(878, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */ + BT_DEVICE(879, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */ + BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Viewcast Osprey 200 */ + { } +}; +MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); + +/* cards known not to have audio + * (DVB cards use the audio function to transfer MPEG data) */ +static struct { + unsigned short subvendor, subdevice; +} blacklist[] __devinitdata = { + {0x0071, 0x0101}, /* Nebula Electronics DigiTV */ + {0x11bd, 0x0026}, /* Pinnacle PCTV SAT CI */ + {0x1461, 0x0761}, /* AVermedia AverTV DVB-T */ + {0x1461, 0x0771}, /* AVermedia DVB-T 771 */ + {0x1822, 0x0001}, /* Twinhan VisionPlus DVB-T */ + {0x18ac, 0xdb10}, /* DVICO FusionHDTV DVB-T Lite */ + {0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */ +}; + +/* return the rate of the card, or a negative value if it's blacklisted */ +static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) +{ + int i; + const struct pci_device_id *supported; + + supported = pci_match_device(snd_bt87x_ids, pci); + if (supported) + return supported->driver_data; + + for (i = 0; i < ARRAY_SIZE(blacklist); ++i) + if (blacklist[i].subvendor == pci->subsystem_vendor && + blacklist[i].subdevice == pci->subsystem_device) { + snd_printdd(KERN_INFO "card %#04x:%#04x has no audio\n", + pci->subsystem_vendor, pci->subsystem_device); + return -EBUSY; + } + + snd_printk(KERN_INFO "unknown card %#04x:%#04x, using default rate 32000\n", + pci->subsystem_vendor, pci->subsystem_device); + snd_printk(KERN_DEBUG "please mail id, board name, and, " + "if it works, the correct digital_rate option to " + "\n"); + return 32000; /* default rate */ +} + static int __devinit snd_bt87x_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { static int dev; snd_card_t *card; bt87x_t *chip; - int err; + int err, rate; + + rate = pci_id->driver_data; + if (! rate) + if ((rate = snd_bt87x_detect_card(pci)) <= 0) + return -ENODEV; if (dev >= SNDRV_CARDS) return -ENODEV; @@ -763,7 +851,7 @@ if (digital_rate[dev] > 0) chip->dig_rate = digital_rate[dev]; else - chip->dig_rate = (int)pci_id->driver_data; + chip->dig_rate = rate; err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital"); if (err < 0) @@ -807,22 +895,13 @@ pci_set_drvdata(pci, NULL); } -#define BT_DEVICE(chip, subvend, subdev, rate) \ - { .vendor = PCI_VENDOR_ID_BROOKTREE, \ - .device = PCI_DEVICE_ID_BROOKTREE_##chip, \ - .subvendor = subvend, .subdevice = subdev, \ - .driver_data = rate } - -/* driver_data is the default digital_rate value for that device */ -static struct pci_device_id snd_bt87x_ids[] = { - BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Osprey 200 */ - - /* default entries for 32kHz and generic Bt87x cards */ - BT_DEVICE(878, PCI_ANY_ID, PCI_ANY_ID, 32000), - BT_DEVICE(879, PCI_ANY_ID, PCI_ANY_ID, 32000), +/* default entries for all Bt87x cards - it's not exported */ +/* driver_data is set to 0 to call detection */ +static struct pci_device_id snd_bt87x_default_ids[] = { + BT_DEVICE(878, PCI_ANY_ID, PCI_ANY_ID, 0), + BT_DEVICE(879, PCI_ANY_ID, PCI_ANY_ID, 0), { } }; -MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); static struct pci_driver driver = { .name = "Bt87x", @@ -833,6 +912,8 @@ static int __init alsa_card_bt87x_init(void) { + if (load_all) + driver.id_table = snd_bt87x_default_ids; return pci_module_init(&driver); } diff -Nru a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile --- a/sound/pci/emu10k1/Makefile 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/emu10k1/Makefile 2004-11-17 19:39:27 -08:00 @@ -5,7 +5,7 @@ snd-emu10k1-objs := emu10k1.o emu10k1_main.o \ irq.o memory.o voice.o emumpu401.o emupcm.o io.o \ - emuproc.o emumixer.o emufx.o + emuproc.o emumixer.o emufx.o timer.o snd-emu10k1-synth-objs := emu10k1_synth.o emu10k1_callback.o emu10k1_patch.o # diff -Nru a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c --- a/sound/pci/emu10k1/emu10k1.c 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/emu10k1/emu10k1.c 2004-11-17 19:39:27 -08:00 @@ -124,6 +124,12 @@ snd_card_free(card); return err; } + + if ((err = snd_emu10k1_timer(emu, 0)) < 0) { + snd_card_free(card); + return err; + } + if (emu->audigy) { if ((err = snd_emu10k1_audigy_midi(emu)) < 0) { snd_card_free(card); diff -Nru a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c --- a/sound/pci/emu10k1/emufx.c 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/emu10k1/emufx.c 2004-11-17 19:39:27 -08:00 @@ -437,7 +437,7 @@ } int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu, - snd_emu10k1_fx8010_irq_t *irq) + snd_emu10k1_fx8010_irq_t *irq) { snd_emu10k1_fx8010_irq_t *tmp; unsigned long flags; @@ -470,8 +470,8 @@ { snd_assert(*ptr < 512, return); set_bit(*ptr, icode->code_valid); - icode->code[*ptr ][0] = ((x & 0x3ff) << 10) | (y & 0x3ff); - icode->code[(*ptr)++][1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff); + icode->code[(*ptr) * 2 + 0] = ((x & 0x3ff) << 10) | (y & 0x3ff); + icode->code[(*ptr)++ * 2 + 1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff); } #define OP(icode, ptr, op, r, a, x, y) \ @@ -482,8 +482,8 @@ { snd_assert(*ptr < 1024, return); set_bit(*ptr, icode->code_valid); - icode->code[*ptr ][0] = ((x & 0x7ff) << 12) | (y & 0x7ff); - icode->code[(*ptr)++][1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff); + icode->code[(*ptr) * 2 + 0] = ((x & 0x7ff) << 12) | (y & 0x7ff); + icode->code[(*ptr)++ * 2 + 1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff); } #define A_OP(icode, ptr, op, r, a, x, y) \ @@ -501,83 +501,108 @@ return snd_emu10k1_ptr_read(emu, pc, 0); } -static void snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) +static int snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) { int gpr; + u32 val; for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) { if (!test_bit(gpr, icode->gpr_valid)) continue; - snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, icode->gpr_map[gpr]); + if (get_user(val, &icode->gpr_map[gpr])) + return -EFAULT; + snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val); } + return 0; } -static void snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) +static int snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) { int gpr; + u32 val; for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) { set_bit(gpr, icode->gpr_valid); - icode->gpr_map[gpr] = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0); + val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0); + if (put_user(val, &icode->gpr_map[gpr])) + return -EFAULT; } + return 0; } -static void snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) +static int snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) { int tram; + u32 addr, val; for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) { if (!test_bit(tram, icode->tram_valid)) continue; - snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, icode->tram_data_map[tram]); - if (!emu->audigy) - snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram]); - else { - snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram] << 12); - snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, icode->tram_addr_map[tram] >> 20); + if (get_user(val, &icode->tram_data_map[tram]) || + get_user(addr, &icode->tram_addr_map[tram])) + return -EFAULT; + snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val); + if (!emu->audigy) { + snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr); + } else { + snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12); + snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20); } } + return 0; } -static void snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) +static int snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) { int tram; + u32 val, addr; memset(icode->tram_valid, 0, sizeof(icode->tram_valid)); for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) { set_bit(tram, icode->tram_valid); - icode->tram_data_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0); - if (!emu->audigy) - icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0); - else { - icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12; - icode->tram_addr_map[tram] |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20; + val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0); + if (!emu->audigy) { + addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0); + } else { + addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12; + addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20; } + if (put_user(val, &icode->tram_data_map[tram]) || + put_user(addr, &icode->tram_addr_map[tram])) + return -EFAULT; } + return 0; } -static void snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) +static int snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) { - u32 pc; + u32 pc, lo, hi; - for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) { - if (!test_bit(pc, icode->code_valid)) + for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) { + if (!test_bit(pc / 2, icode->code_valid)) continue; - snd_emu10k1_efx_write(emu, pc * 2, icode->code[pc][0]); - snd_emu10k1_efx_write(emu, pc * 2 + 1, icode->code[pc][1]); + if (get_user(lo, &icode->code[pc + 0]) || + get_user(hi, &icode->code[pc + 1])) + return -EFAULT; + snd_emu10k1_efx_write(emu, pc + 0, lo); + snd_emu10k1_efx_write(emu, pc + 1, hi); } + return 0; } -static void snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) +static int snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) { u32 pc; memset(icode->code_valid, 0, sizeof(icode->code_valid)); - for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) { - set_bit(pc, icode->code_valid); - icode->code[pc][0] = snd_emu10k1_efx_read(emu, pc * 2); - icode->code[pc][1] = snd_emu10k1_efx_read(emu, pc * 2 + 1); + for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) { + set_bit(pc / 2, icode->code_valid); + if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0])) + return -EFAULT; + if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1])) + return -EFAULT; } + return 0; } static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id) @@ -647,7 +672,7 @@ kfree(ctl); } -static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) +static int snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) { unsigned int i, j; emu10k1_fx8010_control_gpr_t __user *_gctl; @@ -656,17 +681,20 @@ snd_kcontrol_new_t knew; snd_kcontrol_t *kctl; snd_ctl_elem_value_t *val; + int err = 0; val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL); if (!val) - return; + return -ENOMEM; for (i = 0, _gctl = icode->gpr_add_controls; i < icode->gpr_add_control_count; i++, _gctl++) { - if (copy_from_user(&gctl, _gctl, sizeof(gctl))) - break; + if (copy_from_user(&gctl, _gctl, sizeof(gctl))) { + err = -EFAULT; + goto __error; + } snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER || - gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, continue); - snd_runtime_check(gctl.id.name[0] != '\0', continue); + gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error); + snd_runtime_check(gctl.id.name[0] != '\0', err = -EINVAL; goto __error); ctl = snd_emu10k1_look_for_ctl(emu, &gctl.id); memset(&knew, 0, sizeof(knew)); knew.iface = gctl.id.iface; @@ -694,9 +722,9 @@ continue; knew.private_value = (unsigned long)ctl; memcpy(ctl, &nctl, sizeof(nctl)); - if (snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu)) < 0) { + if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) { kfree(ctl); - continue; + goto __error; } kctl->private_free = snd_emu10k1_ctl_private_free; ctl->kcontrol = kctl; @@ -711,10 +739,12 @@ } snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val); } + __error: kfree(val); + return err; } -static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) +static int snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) { unsigned int i; snd_ctl_elem_id_t id; @@ -724,13 +754,14 @@ for (i = 0, _id = icode->gpr_del_controls; i < icode->gpr_del_control_count; i++, _id++) { - snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, continue); + snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, return -EFAULT); down_write(&card->controls_rwsem); ctl = snd_emu10k1_look_for_ctl(emu, &id); if (ctl) snd_ctl_remove(card, ctl->kcontrol); up_write(&card->controls_rwsem); } + return 0; } static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) @@ -789,11 +820,12 @@ else snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP); /* ok, do the main job */ - snd_emu10k1_del_controls(emu, icode); - snd_emu10k1_gpr_poke(emu, icode); - snd_emu10k1_tram_poke(emu, icode); - snd_emu10k1_code_poke(emu, icode); - snd_emu10k1_add_controls(emu, icode); + if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 || + (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 || + (err = snd_emu10k1_tram_poke(emu, icode)) < 0 || + (err = snd_emu10k1_code_poke(emu, icode)) < 0 || + (err = snd_emu10k1_add_controls(emu, icode)) < 0) + goto __error; /* start FX processor when the DSP code is updated */ if (emu->audigy) snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg); @@ -811,10 +843,13 @@ down(&emu->fx8010.lock); strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name)); /* ok, do the main job */ - snd_emu10k1_gpr_peek(emu, icode); - snd_emu10k1_tram_peek(emu, icode); - snd_emu10k1_code_peek(emu, icode); - err = snd_emu10k1_list_controls(emu, icode); + err = snd_emu10k1_gpr_peek(emu, icode); + if (err >= 0) + err = snd_emu10k1_tram_peek(emu, icode); + if (err >= 0) + err = snd_emu10k1_code_peek(emu, icode); + if (err >= 0) + err = snd_emu10k1_list_controls(emu, icode); up(&emu->fx8010.lock); return err; } @@ -957,20 +992,24 @@ const int stereo_mix = capture + 2; const int tmp = 0x88; u32 ptr; - emu10k1_fx8010_code_t *icode; - emu10k1_fx8010_control_gpr_t *controls, *ctl; + emu10k1_fx8010_code_t *icode = NULL; + emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl; mm_segment_t seg; spin_lock_init(&emu->fx8010.irq_lock); INIT_LIST_HEAD(&emu->fx8010.gpr_ctl); - if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL) - return -ENOMEM; - if ((controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) { - kfree(icode); - return -ENOMEM; + if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL || + (icode->gpr_map = kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), GFP_KERNEL)) == NULL || + (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) { + err = -ENOMEM; + goto __err; } + icode->tram_data_map = icode->gpr_map + 512; + icode->tram_addr_map = icode->tram_data_map + 256; + icode->code = icode->tram_addr_map + 256; + /* clear free GPRs */ for (i = 0; i < 512; i++) set_bit(i, icode->gpr_valid); @@ -1335,8 +1374,13 @@ snd_leave_user(seg); __err: - kfree(controls); - kfree(icode); + if (controls != NULL) + kfree(controls); + if (icode != NULL) { + if (icode->gpr_map != NULL) + kfree(icode->gpr_map); + kfree(icode); + } return err; } @@ -1398,8 +1442,8 @@ int err, i, z, gpr, tmp, playback, capture; u32 ptr; emu10k1_fx8010_code_t *icode; - emu10k1_fx8010_pcm_t *ipcm; - emu10k1_fx8010_control_gpr_t *controls, *ctl; + emu10k1_fx8010_pcm_t *ipcm = NULL; + emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl; mm_segment_t seg; spin_lock_init(&emu->fx8010.irq_lock); @@ -1407,15 +1451,16 @@ if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL) return -ENOMEM; - if ((controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL) { - kfree(icode); - return -ENOMEM; - } - if ((ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) { - kfree(controls); - kfree(icode); - return -ENOMEM; + if ((icode->gpr_map = kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t), GFP_KERNEL)) == NULL || + (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL || + (ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) { + err = -ENOMEM; + goto __err; } + + icode->tram_data_map = icode->gpr_map + 256; + icode->tram_addr_map = icode->tram_data_map + 160; + icode->code = icode->tram_addr_map + 160; /* clear free GPRs */ for (i = 0; i < 256; i++) @@ -1906,9 +1951,15 @@ if (err >= 0) err = snd_emu10k1_ipcm_poke(emu, ipcm); __err: - kfree(ipcm); - kfree(controls); - kfree(icode); + if (ipcm != NULL) + kfree(ipcm); + if (controls != NULL) + kfree(controls); + if (icode != NULL) { + if (icode->gpr_map != NULL) + kfree(icode->gpr_map); + kfree(icode); + } return err; } diff -Nru a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c --- a/sound/pci/emu10k1/irq.c 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/emu10k1/irq.c 2004-11-17 19:39:27 -08:00 @@ -112,8 +112,8 @@ status &= ~(IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2); } if (status & IPR_INTERVALTIMER) { - if (emu->timer_interrupt) - emu->timer_interrupt(emu); + if (emu->timer) + snd_timer_interrupt(emu->timer, emu->timer->sticks); else snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB); status &= ~IPR_INTERVALTIMER; diff -Nru a/sound/pci/emu10k1/timer.c b/sound/pci/emu10k1/timer.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/sound/pci/emu10k1/timer.c 2004-11-17 19:39:27 -08:00 @@ -0,0 +1,99 @@ +/* + * Copyright (c) by Lee Revell + * + * Routines for control of EMU10K1 chips + * + * Copied from similar code by Clemens Ladisch in the ymfpci driver + * + * BUGS: + * -- + * + * TODO: + * -- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include + +static int snd_emu10k1_timer_start(snd_timer_t *timer) +{ + emu10k1_t *emu; + unsigned long flags; + unsigned int delay; + + emu = snd_timer_chip(timer); + delay = timer->sticks - 1; + if (delay < 5 ) /* minimum time is 5 ticks */ + delay = 5; + spin_lock_irqsave(&emu->reg_lock, flags); + snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB); + outw(delay & TIMER_RATE_MASK, emu->port + TIMER); + spin_unlock_irqrestore(&emu->reg_lock, flags); + return 0; +} + +static int snd_emu10k1_timer_stop(snd_timer_t *timer) +{ + emu10k1_t *emu; + unsigned long flags; + + emu = snd_timer_chip(timer); + spin_lock_irqsave(&emu->reg_lock, flags); + snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB); + spin_unlock_irqrestore(&emu->reg_lock, flags); + return 0; +} + +static int snd_emu10k1_timer_precise_resolution(snd_timer_t *timer, + unsigned long *num, unsigned long *den) +{ + *num = 1; + *den = 48000; + return 0; +} + +static struct _snd_timer_hardware snd_emu10k1_timer_hw = { + .flags = SNDRV_TIMER_HW_AUTO, + .resolution = 20833, /* 1 sample @ 48KHZ = 20.833...us */ + .ticks = 1024, + .start = snd_emu10k1_timer_start, + .stop = snd_emu10k1_timer_stop, + .precise_resolution = snd_emu10k1_timer_precise_resolution, +}; + +int __devinit snd_emu10k1_timer(emu10k1_t *emu, int device) +{ + snd_timer_t *timer = NULL; + snd_timer_id_t tid; + int err; + + tid.dev_class = SNDRV_TIMER_CLASS_CARD; + tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; + tid.card = emu->card->number; + tid.device = device; + tid.subdevice = 0; + if ((err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer)) >= 0) { + strcpy(timer->name, "EMU10K1 timer"); + timer->private_data = emu; + timer->hw = snd_emu10k1_timer_hw; + } + emu->timer = timer; + return err; +} diff -Nru a/sound/pci/es1968.c b/sound/pci/es1968.c --- a/sound/pci/es1968.c 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/es1968.c 2004-11-17 19:39:27 -08:00 @@ -837,23 +837,19 @@ static void snd_es1968_bob_stop(es1968_t *chip) { u16 reg; - unsigned long flags; - spin_lock_irqsave(&chip->reg_lock, flags); reg = __maestro_read(chip, 0x11); reg &= ~ESM_BOB_ENABLE; __maestro_write(chip, 0x11, reg); reg = __maestro_read(chip, 0x17); reg &= ~ESM_BOB_START; __maestro_write(chip, 0x17, reg); - spin_unlock_irqrestore(&chip->reg_lock, flags); } static void snd_es1968_bob_start(es1968_t *chip) { int prescale; int divide; - unsigned long flags; /* compute ideal interrupt frequency for buffer size & play rate */ /* first, find best prescaler value to match freq */ @@ -882,13 +878,11 @@ } else if (divide > 1) divide--; - spin_lock_irqsave(&chip->reg_lock, flags); __maestro_write(chip, 6, 0x9000 | (prescale << 5) | divide); /* set reg */ /* Now set IDR 11/17 */ __maestro_write(chip, 0x11, __maestro_read(chip, 0x11) | 1); __maestro_write(chip, 0x17, __maestro_read(chip, 0x17) | 1); - spin_unlock_irqrestore(&chip->reg_lock, flags); } /* call with substream spinlock */ diff -Nru a/sound/pci/trident/trident_synth.c b/sound/pci/trident/trident_synth.c --- a/sound/pci/trident/trident_synth.c 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/trident/trident_synth.c 2004-11-17 19:39:27 -08:00 @@ -618,7 +618,7 @@ instr = snd_seq_instr_find(trident->synth.ilist, &v->instr, 0, 1); if (instr != NULL) { if (instr->ops) { - if (instr->ops->instr_type == snd_seq_simple_id) + if (!strcmp(instr->ops->instr_type, SNDRV_SEQ_INSTR_ID_SIMPLE)) snd_trident_simple_init(v); } snd_seq_instr_free_use(trident->synth.ilist, instr); diff -Nru a/sound/pci/via82xx.c b/sound/pci/via82xx.c --- a/sound/pci/via82xx.c 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/via82xx.c 2004-11-17 19:39:27 -08:00 @@ -2115,6 +2115,7 @@ { .vendor = 0x1631, .device = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */ { .vendor = 0x1695, .device = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */ { .vendor = 0x1849, .device = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */ + { .vendor = 0x147b, .device = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */ { } /* terminator */ }; struct dxs_whitelist *w; diff -Nru a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c --- a/sound/pci/vx222/vx222.c 2004-11-17 19:39:27 -08:00 +++ b/sound/pci/vx222/vx222.c 2004-11-17 19:39:27 -08:00 @@ -61,8 +61,8 @@ }; static struct pci_device_id snd_vx222_ids[] = { - { 0x10b5, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */ - { 0x10b5, 0x9030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */ + { 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */ + { 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */ { 0, } }; diff -Nru a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c --- a/sound/sparc/cs4231.c 2004-11-17 19:39:27 -08:00 +++ b/sound/sparc/cs4231.c 2004-11-17 19:39:27 -08:00 @@ -560,7 +560,6 @@ { unsigned long flags; int timeout; - signed long time; spin_lock_irqsave(&chip->lock, flags); snd_cs4231_busy_wait(chip); @@ -594,29 +593,29 @@ #if 0 printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies); #endif - time = HZ / 4; + /* in 10ms increments, check condition, up to 250ms */ + timeout = 25; while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) { spin_unlock_irqrestore(&chip->lock, flags); - if (time <= 0) { + if (--timeout < 0) { snd_printk("mce_down - auto calibration time out (2)\n"); return; } - set_current_state(TASK_INTERRUPTIBLE); - time = schedule_timeout(time); + msleep(10); spin_lock_irqsave(&chip->lock, flags); } #if 0 printk("(3) jiffies = %li\n", jiffies); #endif - time = HZ / 10; + /* in 10ms increments, check condition, up to 100ms */ + timeout = 10; while (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) { spin_unlock_irqrestore(&chip->lock, flags); - if (time <= 0) { + if (--timeout < 0) { snd_printk("mce_down - auto calibration time out (3)\n"); return; } - set_current_state(TASK_INTERRUPTIBLE); - time = schedule_timeout(time); + msleep(10); spin_lock_irqsave(&chip->lock, flags); } spin_unlock_irqrestore(&chip->lock, flags); diff -Nru a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c --- a/sound/usb/usbmixer.c 2004-11-17 19:39:27 -08:00 +++ b/sound/usb/usbmixer.c 2004-11-17 19:39:27 -08:00 @@ -374,7 +374,7 @@ static int check_matrix_bitmap(unsigned char *bmap, int ich, int och, int num_outs) { int idx = ich * num_outs + och; - return bmap[-(idx >> 3)] & (0x80 >> (idx & 7)); + return bmap[idx >> 3] & (0x80 >> (idx & 7)); } @@ -931,14 +931,14 @@ */ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc, - int in_ch, int unitid) + int in_pin, int in_ch, int unitid, + usb_audio_term_t *iterm) { usb_mixer_elem_info_t *cval; - unsigned int num_ins = desc[4]; - unsigned int num_outs = desc[5 + num_ins]; + unsigned int input_pins = desc[4]; + unsigned int num_outs = desc[5 + input_pins]; unsigned int i, len; snd_kcontrol_t *kctl; - usb_audio_term_t iterm; if (check_ignored_ctl(state, unitid, 0)) return; @@ -947,16 +947,13 @@ if (! cval) return; - if (check_input_term(state, desc[5 + in_ch], &iterm) < 0) - return; - cval->chip = state->chip; cval->ctrlif = state->ctrlif; cval->id = unitid; cval->control = in_ch + 1; /* based on 1 */ cval->val_type = USB_MIXER_S16; for (i = 0; i < num_outs; i++) { - if (check_matrix_bitmap(desc + 9 + num_ins, in_ch, i, num_outs)) { + if (check_matrix_bitmap(desc + 9 + input_pins, in_ch, i, num_outs)) { cval->cmask |= (1 << i); cval->channels++; } @@ -975,9 +972,9 @@ len = check_mapped_name(state, unitid, 0, kctl->id.name, sizeof(kctl->id.name)); if (! len) - len = get_term_name(state, &iterm, kctl->id.name, sizeof(kctl->id.name), 0); + len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0); if (! len) - len = sprintf(kctl->id.name, "Mixer Source %d", in_ch); + len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1); strlcat(kctl->id.name + len, " Volume", sizeof(kctl->id.name)); snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n", @@ -991,17 +988,44 @@ */ static int parse_audio_mixer_unit(mixer_build_t *state, int unitid, unsigned char *desc) { - int num_ins, num_outs; - int i, err; - if (desc[0] < 12 || ! (num_ins = desc[4]) || ! (num_outs = desc[5 + num_ins])) + usb_audio_term_t iterm; + int input_pins, num_ins, num_outs; + int pin, ich, err; + + if (desc[0] < 11 || ! (input_pins = desc[4]) || ! (num_outs = desc[5 + input_pins])) { + snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid); return -EINVAL; + } + /* no bmControls field (e.g. Maya44) -> ignore */ + if (desc[0] <= 10 + input_pins) { + snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid); + return 0; + } - for (i = 0; i < num_ins; i++) { - err = parse_audio_unit(state, desc[5 + i]); + num_ins = 0; + ich = 0; + for (pin = 0; pin < input_pins; pin++) { + err = parse_audio_unit(state, desc[5 + pin]); if (err < 0) return err; - if (check_matrix_bitmap(desc + 9 + num_ins, i, 0, num_outs)) - build_mixer_unit_ctl(state, desc, i, unitid); + err = check_input_term(state, desc[5 + pin], &iterm); + if (err < 0) + return err; + num_ins += iterm.channels; + for (; ich < num_ins; ++ich) { + int och, ich_has_controls = 0; + + for (och = 0; och < num_outs; ++och) { + if (check_matrix_bitmap(desc + 9 + input_pins, + ich, och, num_outs)) { + ich_has_controls = 1; + break; + } + } + if (ich_has_controls) + build_mixer_unit_ctl(state, desc, pin, ich, + unitid, &iterm); + } } return 0; } diff -Nru a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c --- a/sound/usb/usx2y/usX2Yhwdep.c 2004-11-17 19:39:27 -08:00 +++ b/sound/usb/usx2y/usX2Yhwdep.c 2004-11-17 19:39:27 -08:00 @@ -95,20 +95,14 @@ { unsigned int mask = 0; usX2Ydev_t *us428 = (usX2Ydev_t*)hw->private_data; - static unsigned LastN; - + us428ctls_sharedmem_t *shm = us428->us428ctls_sharedmem; if (us428->chip_status & USX2Y_STAT_CHIP_HUP) return POLLHUP; poll_wait(file, &us428->us428ctls_wait_queue_head, wait); - down(&us428->open_mutex); - if (us428->us428ctls_sharedmem - && us428->us428ctls_sharedmem->CtlSnapShotLast != LastN) { + if (shm != NULL && shm->CtlSnapShotLast != shm->CtlSnapShotRed) mask |= POLLIN; - LastN = us428->us428ctls_sharedmem->CtlSnapShotLast; - } - up(&us428->open_mutex); return mask; } diff -Nru a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c --- a/sound/usb/usx2y/usbusx2y.c 2004-11-17 19:39:27 -08:00 +++ b/sound/usb/usx2y/usbusx2y.c 2004-11-17 19:39:27 -08:00 @@ -1,6 +1,22 @@ /* - * usbus428.c - ALSA USB US-428 Driver + * usbusy2y.c - ALSA USB US-428 Driver * +2004-10-26 Karsten Wiese + Version 0.8.6: + wake_up() process waiting in usX2Y_urbs_start() on error. + +2004-10-21 Karsten Wiese + Version 0.8.5: + nrpacks is runtime or compiletime configurable now with tested values from 1 to 4. + +2004-10-03 Karsten Wiese + Version 0.8.2: + Avoid any possible racing while in prepare callback. + +2004-09-30 Karsten Wiese + Version 0.8.0: + Simplified things and made ohci work again. + 2004-09-20 Karsten Wiese Version 0.7.3: Use usb_kill_urb() instead of deprecated (kernel 2.6.9) usb_unlink_urb(). @@ -84,7 +100,7 @@ Version 0.0.2: midi works with snd-usb-midi, audio (only fullduplex now) with i.e. bristol. The firmware has been sniffed from win2k us-428 driver 3.09. - * Copyright (c) 2002 Karsten Wiese + * Copyright (c) 2002 - 2004 Karsten Wiese * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -119,7 +135,7 @@ MODULE_AUTHOR("Karsten Wiese "); -MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.7.3"); +MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.6"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}"); @@ -325,7 +341,8 @@ card->private_free = snd_usX2Y_card_private_free; usX2Y(card)->chip.dev = device; usX2Y(card)->chip.card = card; - init_MUTEX (&usX2Y(card)->open_mutex); + init_waitqueue_head(&usX2Y(card)->prepare_wait_queue); + init_MUTEX (&usX2Y(card)->prepare_mutex); INIT_LIST_HEAD(&usX2Y(card)->chip.midi_list); strcpy(card->driver, "USB "NAME_ALLCAPS""); sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); diff -Nru a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h --- a/sound/usb/usx2y/usbusx2y.h 2004-11-17 19:39:27 -08:00 +++ b/sound/usb/usx2y/usbusx2y.h 2004-11-17 19:39:27 -08:00 @@ -3,15 +3,8 @@ #include "../usbaudio.h" #include "usbus428ctldefs.h" -#define NRURBS 2 /* */ -#define NRPACKS 1 /* FIXME: Currently only 1 works. - usb-frames/ms per urb: 1 and 2 are supported. - setting to 2 will PERHAPS make it easier for slow machines. - Jitter will be higher though. - On my PIII 500Mhz Laptop setting to 1 is the only way to go - for PLAYING synths. i.e. Jack & Aeolus sound quit nicely - at 4 periods 64 frames. - */ +#define NRURBS 2 + #define URBS_AsyncSeq 10 #define URB_DataLen_AsyncSeq 32 @@ -40,13 +33,41 @@ snd_usX2Y_AsyncSeq_t AS04; unsigned int rate, format; - int refframes; int chip_status; - struct semaphore open_mutex; + struct semaphore prepare_mutex; us428ctls_sharedmem_t *us428ctls_sharedmem; + int wait_iso_frame; wait_queue_head_t us428ctls_wait_queue_head; - snd_usX2Y_substream_t *substream[4]; + snd_usX2Y_substream_t *subs[4]; + snd_usX2Y_substream_t * volatile prepare_subs; + wait_queue_head_t prepare_wait_queue; } usX2Ydev_t; + + +struct snd_usX2Y_substream { + usX2Ydev_t *usX2Y; + snd_pcm_substream_t *pcm_substream; + + int endpoint; + unsigned int maxpacksize; /* max packet size in bytes */ + + atomic_t state; +#define state_STOPPED 0 +#define state_STARTING1 1 +#define state_STARTING2 2 +#define state_STARTING3 3 +#define state_PREPARED 4 +#define state_PRERUNNING 6 +#define state_RUNNING 8 + + int hwptr; /* free frame position in the buffer (only for playback) */ + int hwptr_done; /* processed frame position in the buffer */ + int transfer_done; /* processed frames since last period update */ + + struct urb *urb[NRURBS]; /* data urb table */ + struct urb *completed_urb; + char *tmpbuf; /* temporary buffer for playback */ +}; #define usX2Y(c) ((usX2Ydev_t*)(c)->private_data) diff -Nru a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c --- a/sound/usb/usx2y/usbusx2yaudio.c 2004-11-17 19:39:27 -08:00 +++ b/sound/usb/usx2y/usbusx2yaudio.c 2004-11-17 19:39:27 -08:00 @@ -1,10 +1,9 @@ /* - * US-428 AUDIO - - * Copyright (c) 2002-2003 by Karsten Wiese - + * US-X2Y AUDIO + * Copyright (c) 2002-2004 by Karsten Wiese + * * based on - + * * (Tentative) USB Audio Driver for ALSA * * Main and PCM part @@ -42,33 +41,30 @@ #include "usx2y.h" #include "usbusx2y.h" - -struct snd_usX2Y_substream { - usX2Ydev_t *usX2Y; - snd_pcm_substream_t *pcm_substream; - - unsigned char endpoint; - unsigned int datapipe; /* the data i/o pipe */ - unsigned int maxpacksize; /* max packet size in bytes */ - - char prepared, - running, - stalled; - - int hwptr; /* free frame position in the buffer (only for playback) */ - int hwptr_done; /* processed frame position in the buffer */ - int transfer_done; /* processed frames since last period update */ - - struct urb *urb[NRURBS]; /* data urb table */ - int next_urb_complete; - struct urb *completed_urb; - char *tmpbuf; /* temporary buffer for playback */ - volatile int submitted_urbs; - wait_queue_head_t wait_queue; -}; - - - +#define USX2Y_NRPACKS 4 /* Default value used for nr of packs per urb. + 1 to 4 have been tested ok on uhci. + To use 3 on ohci, you'd need a patch: + look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on + "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425" + . + 1, 2 and 4 work out of the box on ohci, if I recall correctly. + Bigger is safer operation, + smaller gives lower latencies. + */ +#define USX2Y_NRPACKS_VARIABLE y /* If your system works ok with this module's parameter + nrpacks set to 1, you might as well comment + this #define out, and thereby produce smaller, faster code. + You'd also set USX2Y_NRPACKS to 1 then. + */ + +#ifdef USX2Y_NRPACKS_VARIABLE + static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */ + #define nr_of_packs() nrpacks + module_param(nrpacks, int, 0444); + MODULE_PARM_DESC(nrpacks, "Number of packets per URB."); +#else + #define nr_of_packs() USX2Y_NRPACKS +#endif @@ -80,15 +76,15 @@ int i, len, lens = 0, hwptr_done = subs->hwptr_done; usX2Ydev_t *usX2Y = subs->usX2Y; - for (i = 0; i < NRPACKS; i++) { + for (i = 0; i < nr_of_packs(); i++) { cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset; if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */ - snd_printdd("activ frame status %i\n", urb->iso_frame_desc[i].status); + snd_printk("activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status); return urb->iso_frame_desc[i].status; } len = urb->iso_frame_desc[i].actual_length / usX2Y->stride; if (! len) { - snd_printk("0 == len ERROR!\n"); + snd_printd("0 == len ERROR!\n"); continue; } @@ -134,7 +130,7 @@ snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime; count = 0; - for (pack = 0; pack < NRPACKS; pack++) { + for (pack = 0; pack < nr_of_packs(); pack++) { /* calculate the size of a packet */ counts = cap_urb->iso_frame_desc[pack].actual_length / usX2Y->stride; count += counts; @@ -142,28 +138,32 @@ snd_printk("should not be here with counts=%i\n", counts); return -EPIPE; } - /* set up descriptor */ - urb->iso_frame_desc[pack].offset = pack ? urb->iso_frame_desc[pack - 1].offset + urb->iso_frame_desc[pack - 1].length : 0; - urb->iso_frame_desc[pack].length = counts * usX2Y->stride; - } - if (subs->hwptr + count > runtime->buffer_size) { - /* err, the transferred area goes over buffer boundary. - * copy the data to the temp buffer. - */ - int len; - len = runtime->buffer_size - subs->hwptr; - urb->transfer_buffer = subs->tmpbuf; - memcpy(subs->tmpbuf, runtime->dma_area + subs->hwptr * usX2Y->stride, len * usX2Y->stride); - memcpy(subs->tmpbuf + len * usX2Y->stride, runtime->dma_area, (count - len) * usX2Y->stride); - subs->hwptr += count; - subs->hwptr -= runtime->buffer_size; - } else { - /* set the buffer pointer */ - urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride; - if ((subs->hwptr += count) >= runtime->buffer_size) + urb->iso_frame_desc[pack].offset = pack ? + urb->iso_frame_desc[pack - 1].offset + urb->iso_frame_desc[pack - 1].length : + 0; + urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length; + } + if (atomic_read(&subs->state) >= state_PRERUNNING) + if (subs->hwptr + count > runtime->buffer_size) { + /* err, the transferred area goes over buffer boundary. + * copy the data to the temp buffer. + */ + int len; + len = runtime->buffer_size - subs->hwptr; + urb->transfer_buffer = subs->tmpbuf; + memcpy(subs->tmpbuf, runtime->dma_area + subs->hwptr * usX2Y->stride, len * usX2Y->stride); + memcpy(subs->tmpbuf + len * usX2Y->stride, runtime->dma_area, (count - len) * usX2Y->stride); + subs->hwptr += count; + subs->hwptr -= runtime->buffer_size; + } else { + /* set the buffer pointer */ + urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride; + if ((subs->hwptr += count) >= runtime->buffer_size) subs->hwptr -= runtime->buffer_size; - } + } + else + urb->transfer_buffer = subs->tmpbuf; urb->transfer_buffer_length = count * usX2Y->stride; return 0; } @@ -173,14 +173,10 @@ * * update the current position and call callback if a period is processed. */ -inline static int usX2Y_urb_play_retire(snd_usX2Y_substream_t *subs, struct urb *urb) +static void usX2Y_urb_play_retire(snd_usX2Y_substream_t *subs, struct urb *urb) { snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime; - int len = (urb->iso_frame_desc[0].actual_length -#if NRPACKS > 1 - + urb->iso_frame_desc[1].actual_length -#endif - ) / subs->usX2Y->stride; + int len = urb->actual_length / subs->usX2Y->stride; subs->transfer_done += len; subs->hwptr_done += len; @@ -190,224 +186,206 @@ subs->transfer_done -= runtime->period_size; snd_pcm_period_elapsed(subs->pcm_substream); } - return 0; } -inline static int usX2Y_urb_submit(snd_usX2Y_substream_t *subs, struct urb *urb, int frame) +static int usX2Y_urb_submit(snd_usX2Y_substream_t *subs, struct urb *urb, int frame) { int err; if (!urb) return -ENODEV; - urb->start_frame = (frame + NRURBS*NRPACKS) & (1024 - 1); + urb->start_frame = (frame + NRURBS * nr_of_packs()); // let hcd do rollover sanity checks urb->hcpriv = NULL; urb->dev = subs->usX2Y->chip.dev; /* we need to set this at each time */ if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { - snd_printk("%i\n", err); + snd_printk("usb_submit_urb() returned %i\n", err); return err; - } else { - subs->submitted_urbs++; - if (subs->next_urb_complete < 0) - subs->next_urb_complete = 0; } return 0; } - -static inline int frame_distance(int from, int to) +static inline int usX2Y_usbframe_complete(snd_usX2Y_substream_t *capsubs, snd_usX2Y_substream_t *playbacksubs, int frame) { - int distance = to - from; - if (distance < -512) - distance += 1024; - else - if (distance > 511) - distance -= 1024; - return distance; -} + int err, state; + { + struct urb *urb = playbacksubs->completed_urb; + state = atomic_read(&playbacksubs->state); + if (NULL != urb) { + if (state == state_RUNNING) + usX2Y_urb_play_retire(playbacksubs, urb); + else + if (state >= state_PRERUNNING) { + atomic_inc(&playbacksubs->state); + } + } else { + switch (state) { + case state_STARTING1: + urb = playbacksubs->urb[0]; + atomic_inc(&playbacksubs->state); + break; + case state_STARTING2: + urb = playbacksubs->urb[1]; + atomic_inc(&playbacksubs->state); + break; + } + } + if (urb) { + if ((err = usX2Y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb)) || + (err = usX2Y_urb_submit(playbacksubs, urb, frame))) { + return err; + } + } -static void usX2Y_subs_set_next_urb_complete(snd_usX2Y_substream_t *subs) -{ - int next_urb_complete = subs->next_urb_complete + 1; - int distance; - if (next_urb_complete >= NRURBS) - next_urb_complete = 0; - distance = frame_distance(subs->completed_urb->start_frame, - subs->urb[next_urb_complete]->start_frame); - if (1 == distance) { - subs->next_urb_complete = next_urb_complete; - } else { - snd_printdd("distance %i not set_nuc %i %i %i \n", distance, subs->endpoint, next_urb_complete, subs->urb[next_urb_complete]->status); - subs->next_urb_complete = -1; + playbacksubs->completed_urb = NULL; } + state = atomic_read(&capsubs->state); + if (state >= state_PREPARED) { + if (state == state_RUNNING) { + if ((err = usX2Y_urb_capt_retire(capsubs))) + return err; + } else + if (state >= state_PRERUNNING) { + atomic_inc(&capsubs->state); + } + if ((err = usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame))) + return err; + } + capsubs->completed_urb = NULL; + return 0; } -static inline void usX2Y_usbframe_complete(snd_usX2Y_substream_t *capsubs, snd_usX2Y_substream_t *playbacksubs, int frame) +static void usX2Y_clients_stop(usX2Ydev_t *usX2Y) { - { - struct urb *urb; - if ((urb = playbacksubs->completed_urb)) { - if (playbacksubs->prepared) - usX2Y_urb_play_retire(playbacksubs, urb); - usX2Y_subs_set_next_urb_complete(playbacksubs); + int s, u; + for (s = 0; s < 4; s++) { + snd_usX2Y_substream_t *subs = usX2Y->subs[s]; + if (subs) { + snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state)); + atomic_set(&subs->state, state_STOPPED); } - if (playbacksubs->running) { - if (NULL == urb) - urb = playbacksubs->urb[playbacksubs->next_urb_complete + 1]; - if (urb && 0 == usX2Y_urb_play_prepare(playbacksubs, - capsubs->completed_urb, - urb)) { - if (usX2Y_urb_submit(playbacksubs, urb, frame) < 0) - return; - } else - snd_pcm_stop(playbacksubs->pcm_substream, SNDRV_PCM_STATE_XRUN); + } + for (s = 0; s < 4; s++) { + snd_usX2Y_substream_t *subs = usX2Y->subs[s]; + if (subs) { + if (atomic_read(&subs->state) >= state_PRERUNNING) { + snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN); + } + for (u = 0; u < NRURBS; u++) { + struct urb *urb = subs->urb[u]; + if (NULL != urb) + snd_printdd("%i status=%i start_frame=%i\n", u, urb->status, urb->start_frame); + } } - playbacksubs->completed_urb = NULL; } - if (capsubs->running) - usX2Y_urb_capt_retire(capsubs); - usX2Y_subs_set_next_urb_complete(capsubs); - if (capsubs->prepared) - usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame); - capsubs->completed_urb = NULL; + usX2Y->prepare_subs = NULL; + wake_up(&usX2Y->prepare_wait_queue); } - -static void usX2Y_clients_stop(snd_usX2Y_substream_t *subs) +static void usX2Y_error_urb_status(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb) { - usX2Ydev_t *usX2Y = subs->usX2Y; - int i; - for (i = 0; i < 4; i++) { - snd_usX2Y_substream_t *substream = usX2Y->substream[i]; - if (substream && substream->running) - snd_pcm_stop(substream->pcm_substream, SNDRV_PCM_STATE_XRUN); - } + snd_printk("ep=%i stalled with status=%i\n", subs->endpoint, urb->status); + urb->status = 0; + usX2Y_clients_stop(usX2Y); } +static void usX2Y_error_sequence(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb) +{ + snd_printk("Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n" + "Most propably some urb of usb-frame %i is still missing.\n" + "Cause could be too long delays in usb-hcd interrupt handling.\n", + usb_get_current_frame_number(usX2Y->chip.dev), + subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame); + usX2Y_clients_stop(usX2Y); +} static void i_usX2Y_urb_complete(struct urb *urb, struct pt_regs *regs) { snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context; + usX2Ydev_t *usX2Y = subs->usX2Y; - subs->submitted_urbs--; - if (urb->status) { - snd_printk("ep=%i stalled with status=%i\n", subs->endpoint, urb->status); - subs->stalled = 1; - usX2Y_clients_stop(subs); - urb->status = 0; + if (unlikely(atomic_read(&subs->state) < state_PREPARED)) { + snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n", usb_get_current_frame_number(usX2Y->chip.dev), subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", urb->status, urb->start_frame); + return; + } + if (unlikely(urb->status)) { + usX2Y_error_urb_status(usX2Y, subs, urb); return; } - if (urb == subs->urb[subs->next_urb_complete]) { + if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame)) subs->completed_urb = urb; - } else { - snd_printk("Sequence Error!(ep=%i;nuc=%i,frame=%i)\n", - subs->endpoint, subs->next_urb_complete, urb->start_frame); - subs->stalled = 1; - usX2Y_clients_stop(subs); + else { + usX2Y_error_sequence(usX2Y, subs, urb); return; } - if (waitqueue_active(&subs->wait_queue)) - wake_up(&subs->wait_queue); { - snd_usX2Y_substream_t *capsubs = subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE], - *playbacksubs = subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK]; - if (capsubs->completed_urb && - (playbacksubs->completed_urb || - !playbacksubs->prepared || - (playbacksubs->prepared && (playbacksubs->next_urb_complete < 0 || // not started yet - frame_distance(capsubs->completed_urb->start_frame, - playbacksubs->urb[playbacksubs->next_urb_complete]->start_frame) - > 0 || // other expected later - playbacksubs->stalled)))) - usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame); + snd_usX2Y_substream_t *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE], + *playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; + if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED && + (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) { + if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) { + if (nr_of_packs() <= urb->start_frame && + urb->start_frame <= (2 * nr_of_packs() - 1)) // uhci and ohci + usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs(); + else + usX2Y->wait_iso_frame += nr_of_packs(); + } else { + snd_printdd("\n"); + usX2Y_clients_stop(usX2Y); + } + } } } - -static int usX2Y_urbs_capt_start(snd_usX2Y_substream_t *subs) +static void usX2Y_urbs_set_complete(usX2Ydev_t * usX2Y, void (*complete)(struct urb *, struct pt_regs *)) { - int i, err; - - for (i = 0; i < NRURBS; i++) { - unsigned long pack; - struct urb *urb = subs->urb[i]; - urb->dev = subs->usX2Y->chip.dev; - urb->transfer_flags = URB_ISO_ASAP; - for (pack = 0; pack < NRPACKS; pack++) { - urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack; - urb->iso_frame_desc[pack].length = subs->maxpacksize; - } - urb->transfer_buffer_length = subs->maxpacksize * NRPACKS; - if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { - snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err); - return -EPIPE; - } else { - subs->submitted_urbs++; - } - urb->transfer_flags = 0; + int s, u; + for (s = 0; s < 4; s++) { + snd_usX2Y_substream_t *subs = usX2Y->subs[s]; + if (NULL != subs) + for (u = 0; u < NRURBS; u++) { + struct urb * urb = subs->urb[u]; + if (NULL != urb) + urb->complete = complete; + } } - subs->stalled = 0; - subs->next_urb_complete = 0; - subs->prepared = 1; - return 0; } -/* - * wait until all urbs are processed. - */ -static int usX2Y_urbs_wait_clear(snd_usX2Y_substream_t *subs) -{ - int timeout = HZ; - - do { - if (0 == subs->submitted_urbs) - break; - set_current_state(TASK_UNINTERRUPTIBLE); - snd_printdd("snd_usX2Y_urbs_wait_clear waiting\n"); - schedule_timeout(1); - } while (--timeout > 0); - if (subs->submitted_urbs) - snd_printk(KERN_ERR "timeout: still %d active urbs..\n", subs->submitted_urbs); - return 0; -} -/* - * return the current pcm pointer. just return the hwptr_done value. - */ -static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(snd_pcm_substream_t *substream) +static void usX2Y_subs_startup_finish(usX2Ydev_t * usX2Y) { - snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data; - return subs->hwptr_done; + usX2Y_urbs_set_complete(usX2Y, i_usX2Y_urb_complete); + usX2Y->prepare_subs = NULL; } -/* - * start/stop substream - */ -static int snd_usX2Y_pcm_trigger(snd_pcm_substream_t *substream, int cmd) + +static void i_usX2Y_subs_startup(struct urb *urb, struct pt_regs *regs) { - snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data; + snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context; + usX2Ydev_t *usX2Y = subs->usX2Y; + snd_usX2Y_substream_t *prepare_subs = usX2Y->prepare_subs; + if (NULL != prepare_subs) + if (urb->start_frame == prepare_subs->urb[0]->start_frame) { + usX2Y_subs_startup_finish(usX2Y); + atomic_inc(&prepare_subs->state); + wake_up(&usX2Y->prepare_wait_queue); + } - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - snd_printdd("snd_usX2Y_pcm_trigger(START)\n"); - if (subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE]->stalled) - return -EPIPE; - else - subs->running = 1; - break; - case SNDRV_PCM_TRIGGER_STOP: - snd_printdd("snd_usX2Y_pcm_trigger(STOP)\n"); - subs->running = 0; - break; - default: - return -EINVAL; - } - return 0; + i_usX2Y_urb_complete(urb, regs); } +static void usX2Y_subs_prepare(snd_usX2Y_substream_t *subs) +{ + snd_printdd("usX2Y_substream_prepare(%p) ep=%i urb0=%p urb1=%p\n", subs, subs->endpoint, subs->urb[0], subs->urb[1]); + /* reset the pointer */ + subs->hwptr = 0; + subs->hwptr_done = 0; + subs->transfer_done = 0; +} static void usX2Y_urb_release(struct urb** urb, int free_tb) { if (*urb) { + usb_kill_urb(*urb); if (free_tb) kfree((*urb)->transfer_buffer); usb_free_urb(*urb); @@ -415,97 +393,181 @@ } } /* - * release a substream + * release a substreams urbs */ static void usX2Y_urbs_release(snd_usX2Y_substream_t *subs) { int i; - snd_printdd("snd_usX2Y_urbs_release() %i\n", subs->endpoint); - usX2Y_urbs_wait_clear(subs); + snd_printdd("usX2Y_urbs_release() %i\n", subs->endpoint); for (i = 0; i < NRURBS; i++) - usX2Y_urb_release(subs->urb + i, subs != subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK]); + usX2Y_urb_release(subs->urb + i, subs != subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]); if (subs->tmpbuf) { kfree(subs->tmpbuf); subs->tmpbuf = NULL; } } - -static void usX2Y_substream_prepare(snd_usX2Y_substream_t *subs) -{ - snd_printdd("usX2Y_substream_prepare() ep=%i urb0=%p urb1=%p\n", subs->endpoint, subs->urb[0], subs->urb[1]); - /* reset the pointer */ - subs->hwptr = 0; - subs->hwptr_done = 0; - subs->transfer_done = 0; -} - - /* * initialize a substream's urbs */ static int usX2Y_urbs_allocate(snd_usX2Y_substream_t *subs) { int i; - int is_playback = subs == subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK]; + unsigned int datapipe; /* the data i/o pipe */ + int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; struct usb_device *dev = subs->usX2Y->chip.dev; - snd_assert(!subs->prepared, return 0); - if (is_playback) { /* allocate a temporary buffer for playback */ - subs->datapipe = usb_sndisocpipe(dev, subs->endpoint); + datapipe = usb_sndisocpipe(dev, subs->endpoint); subs->maxpacksize = dev->epmaxpacketout[subs->endpoint]; if (NULL == subs->tmpbuf) { - subs->tmpbuf = kcalloc(NRPACKS, subs->maxpacksize, GFP_KERNEL); + subs->tmpbuf = kcalloc(nr_of_packs(), subs->maxpacksize, GFP_KERNEL); if (NULL == subs->tmpbuf) { snd_printk(KERN_ERR "cannot malloc tmpbuf\n"); return -ENOMEM; } } } else { - subs->datapipe = usb_rcvisocpipe(dev, subs->endpoint); + datapipe = usb_rcvisocpipe(dev, subs->endpoint); subs->maxpacksize = dev->epmaxpacketin[subs->endpoint]; } /* allocate and initialize data urbs */ for (i = 0; i < NRURBS; i++) { struct urb** purb = subs->urb + i; - if (*purb) + if (*purb) { + usb_kill_urb(*purb); continue; - *purb = usb_alloc_urb(NRPACKS, GFP_KERNEL); + } + *purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL); if (NULL == *purb) { usX2Y_urbs_release(subs); return -ENOMEM; } if (!is_playback && !(*purb)->transfer_buffer) { /* allocate a capture buffer per urb */ - (*purb)->transfer_buffer = kmalloc(subs->maxpacksize*NRPACKS, GFP_KERNEL); + (*purb)->transfer_buffer = kmalloc(subs->maxpacksize * nr_of_packs(), GFP_KERNEL); if (NULL == (*purb)->transfer_buffer) { usX2Y_urbs_release(subs); return -ENOMEM; } } (*purb)->dev = dev; - (*purb)->pipe = subs->datapipe; - (*purb)->number_of_packets = NRPACKS; + (*purb)->pipe = datapipe; + (*purb)->number_of_packets = nr_of_packs(); (*purb)->context = subs; (*purb)->interval = 1; - (*purb)->complete = snd_usb_complete_callback(i_usX2Y_urb_complete); + (*purb)->complete = i_usX2Y_subs_startup; } return 0; } -static void i_usX2Y_04Int(struct urb* urb, struct pt_regs *regs) +static void usX2Y_subs_startup(snd_usX2Y_substream_t *subs) { - usX2Ydev_t* usX2Y = urb->context; - - if (urb->status) { - snd_printk("snd_usX2Y_04Int() urb->status=%i\n", urb->status); - return; + usX2Ydev_t *usX2Y = subs->usX2Y; + usX2Y->prepare_subs = subs; + subs->urb[0]->start_frame = -1; + wmb(); + usX2Y_urbs_set_complete(usX2Y, i_usX2Y_subs_startup); +} + +static int usX2Y_urbs_start(snd_usX2Y_substream_t *subs) +{ + int i, err; + usX2Ydev_t *usX2Y = subs->usX2Y; + + if ((err = usX2Y_urbs_allocate(subs)) < 0) + return err; + subs->completed_urb = NULL; + for (i = 0; i < 4; i++) { + snd_usX2Y_substream_t *subs = usX2Y->subs[i]; + if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED) + goto start; } - if (0 == --usX2Y->US04->len) - wake_up(&usX2Y->In04WaitQueue); + usX2Y->wait_iso_frame = -1; + start: + { + usX2Y_subs_startup(subs); + for (i = 0; i < NRURBS; i++) { + struct urb *urb = subs->urb[i]; + if (usb_pipein(urb->pipe)) { + unsigned long pack; + if (0 == i) + atomic_set(&subs->state, state_STARTING3); + urb->dev = usX2Y->chip.dev; + urb->transfer_flags = URB_ISO_ASAP; + for (pack = 0; pack < nr_of_packs(); pack++) { + urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack; + urb->iso_frame_desc[pack].length = subs->maxpacksize; + } + urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); + if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { + snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err); + err = -EPIPE; + goto cleanup; + } else { + if (0 > usX2Y->wait_iso_frame) + usX2Y->wait_iso_frame = urb->start_frame; + } + urb->transfer_flags = 0; + } else { + atomic_set(&subs->state, state_STARTING1); + break; + } + } + err = 0; + wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs); + if (atomic_read(&subs->state) != state_PREPARED) { + err = -EPIPE; + } + + cleanup: + if (err) { + usX2Y_subs_startup_finish(usX2Y); + usX2Y_clients_stop(usX2Y); // something is completely wroong > stop evrything + } + } + return err; +} + +/* + * return the current pcm pointer. just return the hwptr_done value. + */ +static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(snd_pcm_substream_t *substream) +{ + snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data; + return subs->hwptr_done; +} +/* + * start/stop substream + */ +static int snd_usX2Y_pcm_trigger(snd_pcm_substream_t *substream, int cmd) +{ + snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + snd_printdd("snd_usX2Y_pcm_trigger(START)\n"); + if (atomic_read(&subs->state) == state_PREPARED && + atomic_read(&subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]->state) >= state_PREPARED) { + atomic_set(&subs->state, state_PRERUNNING); + } else { + snd_printdd("\n"); + return -EPIPE; + } + break; + case SNDRV_PCM_TRIGGER_STOP: + snd_printdd("snd_usX2Y_pcm_trigger(STOP)\n"); + if (atomic_read(&subs->state) >= state_PRERUNNING) + atomic_set(&subs->state, state_PREPARED); + break; + default: + return -EINVAL; + } + return 0; } + + /* * allocate a buffer, setup samplerate * @@ -592,76 +654,74 @@ }; #define NOOF_SETRATE_URBS ARRAY_SIZE(SetRate48000) +static void i_usX2Y_04Int(struct urb* urb, struct pt_regs *regs) +{ + usX2Ydev_t* usX2Y = urb->context; + + if (urb->status) { + snd_printk("snd_usX2Y_04Int() urb->status=%i\n", urb->status); + } + if (0 == --usX2Y->US04->len) + wake_up(&usX2Y->In04WaitQueue); +} + static int usX2Y_rate_set(usX2Ydev_t *usX2Y, int rate) { int err = 0, i; snd_usX2Y_urbSeq_t *us = NULL; int *usbdata = NULL; - DECLARE_WAITQUEUE(wait, current); struct s_c2 *ra = rate == 48000 ? SetRate48000 : SetRate44100; if (usX2Y->rate != rate) { - do { - us = kmalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL); - if (NULL == us) { + us = kmalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL); + if (NULL == us) { + err = -ENOMEM; + goto cleanup; + } + memset(us, 0, sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS); + usbdata = kmalloc(sizeof(int)*NOOF_SETRATE_URBS, GFP_KERNEL); + if (NULL == usbdata) { + err = -ENOMEM; + goto cleanup; + } + for (i = 0; i < NOOF_SETRATE_URBS; ++i) { + if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) { err = -ENOMEM; - break; + goto cleanup; } - memset(us, 0, sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS); - usbdata = kmalloc(sizeof(int)*NOOF_SETRATE_URBS, GFP_KERNEL); - if (NULL == usbdata) { - err = -ENOMEM; - break; - } - for (i = 0; i < NOOF_SETRATE_URBS; ++i) { - if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) { - err = -ENOMEM; - break; - } - ((char*)(usbdata + i))[0] = ra[i].c1; - ((char*)(usbdata + i))[1] = ra[i].c2; - usb_fill_bulk_urb(us->urb[i], usX2Y->chip.dev, usb_sndbulkpipe(usX2Y->chip.dev, 4), - usbdata + i, 2, i_usX2Y_04Int, usX2Y); + ((char*)(usbdata + i))[0] = ra[i].c1; + ((char*)(usbdata + i))[1] = ra[i].c2; + usb_fill_bulk_urb(us->urb[i], usX2Y->chip.dev, usb_sndbulkpipe(usX2Y->chip.dev, 4), + usbdata + i, 2, i_usX2Y_04Int, usX2Y); #ifdef OLD_USB - us->urb[i]->transfer_flags = USB_QUEUE_BULK; + us->urb[i]->transfer_flags = USB_QUEUE_BULK; #endif - } - if (err) - break; - - add_wait_queue(&usX2Y->In04WaitQueue, &wait); - set_current_state(TASK_INTERRUPTIBLE); - us->submitted = 0; - us->len = NOOF_SETRATE_URBS; - usX2Y->US04 = us; - - do { - signed long timeout = schedule_timeout(HZ/2); - - if (signal_pending(current)) { - err = -ERESTARTSYS; - break; - } - if (0 == timeout) { - err = -ENODEV; - break; - } - usX2Y->rate = rate; - usX2Y->refframes = rate == 48000 ? 47 : 44; - } while (0); - - remove_wait_queue(&usX2Y->In04WaitQueue, &wait); - } while (0); - + } + us->submitted = 0; + us->len = NOOF_SETRATE_URBS; + usX2Y->US04 = us; + wait_event_timeout(usX2Y->In04WaitQueue, 0 == us->len, HZ); + usX2Y->US04 = NULL; + if (us->len) + err = -ENODEV; + cleanup: if (us) { us->submitted = 2*NOOF_SETRATE_URBS; for (i = 0; i < NOOF_SETRATE_URBS; ++i) { - usb_kill_urb(us->urb[i]); - usb_free_urb(us->urb[i]); + struct urb *urb = us->urb[i]; + if (urb->status) { + if (!err) + err = -ENODEV; + usb_kill_urb(urb); + } + usb_free_urb(urb); } usX2Y->US04 = NULL; kfree(usbdata); kfree(us); + if (!err) { + usX2Y->rate = rate; + } } } @@ -745,27 +805,28 @@ { snd_pcm_runtime_t *runtime = substream->runtime; snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data; + down(&subs->usX2Y->prepare_mutex); snd_printdd("snd_usX2Y_hw_free(%p)\n", substream); if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { - snd_usX2Y_substream_t *cap_subs = subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE]; - subs->prepared = 0; + snd_usX2Y_substream_t *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]; + atomic_set(&subs->state, state_STOPPED); usX2Y_urbs_release(subs); if (!cap_subs->pcm_substream || !cap_subs->pcm_substream->runtime || !cap_subs->pcm_substream->runtime->status || cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) { - cap_subs->prepared = 0; + atomic_set(&cap_subs->state, state_STOPPED); usX2Y_urbs_release(cap_subs); } } else { - snd_usX2Y_substream_t *playback_subs = subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK]; - if (!playback_subs->prepared) { - subs->prepared = 0; + snd_usX2Y_substream_t *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; + if (atomic_read(&playback_subs->state) < state_PREPARED) { + atomic_set(&subs->state, state_STOPPED); usX2Y_urbs_release(subs); } } - + up(&subs->usX2Y->prepare_mutex); return snd_pcm_lib_free_pages(substream); } /* @@ -777,71 +838,32 @@ { snd_pcm_runtime_t *runtime = substream->runtime; snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data; - snd_usX2Y_substream_t *capsubs = subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE]; + usX2Ydev_t *usX2Y = subs->usX2Y; + snd_usX2Y_substream_t *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]; int err = 0; snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream); + down(&usX2Y->prepare_mutex); + usX2Y_subs_prepare(subs); // Start hardware streams // SyncStream first.... - if (! capsubs->prepared) { - if (subs->usX2Y->format != runtime->format) - if ((err = usX2Y_format_set(subs->usX2Y, runtime->format)) < 0) - return err; - if (subs->usX2Y->rate != runtime->rate) - if ((err = usX2Y_rate_set(subs->usX2Y, runtime->rate)) < 0) - return err; - snd_printdd("starting capture pipe for playpipe\n"); - usX2Y_urbs_allocate(capsubs); - capsubs->completed_urb = NULL; - { - DECLARE_WAITQUEUE(wait, current); - add_wait_queue(&capsubs->wait_queue, &wait); - if (0 <= (err = usX2Y_urbs_capt_start(capsubs))) { - signed long timeout; - set_current_state(TASK_INTERRUPTIBLE); - timeout = schedule_timeout(HZ/4); - if (signal_pending(current)) - err = -ERESTARTSYS; - else { - snd_printdd("%li\n", HZ/4 - timeout); - if (0 == timeout) - err = -EPIPE; - } - } - remove_wait_queue(&capsubs->wait_queue, &wait); - if (0 > err) - return err; - } + if (atomic_read(&capsubs->state) < state_PREPARED) { + if (usX2Y->format != runtime->format) + if ((err = usX2Y_format_set(usX2Y, runtime->format)) < 0) + goto up_prepare_mutex; + if (usX2Y->rate != runtime->rate) + if ((err = usX2Y_rate_set(usX2Y, runtime->rate)) < 0) + goto up_prepare_mutex; + snd_printdd("starting capture pipe for %s\n", subs == capsubs ? "self" : "playpipe"); + if (0 > (err = usX2Y_urbs_start(capsubs))) + goto up_prepare_mutex; } - if (subs != capsubs) { - int u; - if (!subs->prepared) { - if ((err = usX2Y_urbs_allocate(subs)) < 0) - return err; - subs->prepared = 1; - } - while (subs->submitted_urbs) - for (u = 0; u < NRURBS; u++) { - snd_printdd("%i\n", subs->urb[u]->status); - while(subs->urb[u]->status || NULL != subs->urb[u]->hcpriv) { - signed long timeout; - snd_printdd("ep=%i waiting for urb=%p status=%i hcpriv=%p\n", - subs->endpoint, subs->urb[u], - subs->urb[u]->status, subs->urb[u]->hcpriv); - set_current_state(TASK_INTERRUPTIBLE); - timeout = schedule_timeout(HZ/10); - if (signal_pending(current)) { - return -ERESTARTSYS; - } - } - } - subs->completed_urb = NULL; - subs->next_urb_complete = -1; - subs->stalled = 0; - } + if (subs != capsubs && atomic_read(&subs->state) < state_PREPARED) + err = usX2Y_urbs_start(subs); - usX2Y_substream_prepare(subs); + up_prepare_mutex: + up(&usX2Y->prepare_mutex); return err; } @@ -933,7 +955,7 @@ snd_pcm_t *pcm; int err, i; snd_usX2Y_substream_t **usX2Y_substream = - usX2Y(card)->substream + 2 * usX2Y(card)->chip.pcm_devs; + usX2Y(card)->subs + 2 * usX2Y(card)->chip.pcm_devs; for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; i <= SNDRV_PCM_STREAM_CAPTURE; ++i) { @@ -942,7 +964,6 @@ snd_printk(KERN_ERR "cannot malloc\n"); return -ENOMEM; } - init_waitqueue_head(&usX2Y_substream[i]->wait_queue); usX2Y_substream[i]->usX2Y = usX2Y(card); }