diff options
Diffstat (limited to 'sound/core/seq')
41 files changed, 626 insertions, 2663 deletions
diff --git a/sound/core/seq/Kconfig b/sound/core/seq/Kconfig new file mode 100644 index 00000000000..b851fd890a8 --- /dev/null +++ b/sound/core/seq/Kconfig @@ -0,0 +1,16 @@ +# define SND_XXX_SEQ to min(SND_SEQUENCER,SND_XXX) + +config SND_RAWMIDI_SEQ + def_tristate SND_SEQUENCER && SND_RAWMIDI + +config SND_OPL3_LIB_SEQ + def_tristate SND_SEQUENCER && SND_OPL3_LIB + +config SND_OPL4_LIB_SEQ + def_tristate SND_SEQUENCER && SND_OPL4_LIB + +config SND_SBAWE_SEQ + def_tristate SND_SEQUENCER && SND_SBAWE + +config SND_EMU10K1_SEQ + def_tristate SND_SEQUENCER && SND_EMU10K1 diff --git a/sound/core/seq/Makefile b/sound/core/seq/Makefile index 402e2b4a34c..941f64a853e 100644 --- a/sound/core/seq/Makefile +++ b/sound/core/seq/Makefile @@ -1,13 +1,8 @@ # # Makefile for ALSA -# Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz> +# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz> # -obj-$(CONFIG_SND) += instr/ -ifeq ($(CONFIG_SND_SEQUENCER_OSS),y) - obj-$(CONFIG_SND_SEQUENCER) += oss/ -endif - snd-seq-device-objs := seq_device.o snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \ seq_fifo.o seq_prioq.o seq_timer.o \ @@ -15,30 +10,20 @@ snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \ snd-seq-midi-objs := seq_midi.o snd-seq-midi-emul-objs := seq_midi_emul.o snd-seq-midi-event-objs := seq_midi_event.o -snd-seq-instr-objs := seq_instr.o snd-seq-dummy-objs := seq_dummy.o snd-seq-virmidi-objs := seq_virmidi.o -# -# this function returns: -# "m" - CONFIG_SND_SEQUENCER is m -# <empty string> - CONFIG_SND_SEQUENCER is undefined -# otherwise parameter #1 value -# -sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) - obj-$(CONFIG_SND_SEQUENCER) += snd-seq.o snd-seq-device.o ifeq ($(CONFIG_SND_SEQUENCER_OSS),y) -obj-$(CONFIG_SND_SEQUENCER) += snd-seq-midi-event.o + obj-$(CONFIG_SND_SEQUENCER) += snd-seq-midi-event.o + obj-$(CONFIG_SND_SEQUENCER) += oss/ endif obj-$(CONFIG_SND_SEQ_DUMMY) += snd-seq-dummy.o # Toplevel Module Dependency obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o -obj-$(call sequencer,$(CONFIG_SND_RAWMIDI)) += snd-seq-midi.o snd-seq-midi-event.o -obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o -obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o -obj-$(call sequencer,$(CONFIG_SND_GUS_SYNTH)) += snd-seq-midi-emul.o snd-seq-instr.o -obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-seq-midi-emul.o snd-seq-virmidi.o -obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-seq-midi-emul.o snd-seq-virmidi.o -obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-seq-midi-emul.o snd-seq-instr.o +obj-$(CONFIG_SND_RAWMIDI_SEQ) += snd-seq-midi.o snd-seq-midi-event.o +obj-$(CONFIG_SND_OPL3_LIB_SEQ) += snd-seq-midi-event.o snd-seq-midi-emul.o +obj-$(CONFIG_SND_OPL4_LIB_SEQ) += snd-seq-midi-event.o snd-seq-midi-emul.o +obj-$(CONFIG_SND_SBAWE_SEQ) += snd-seq-midi-emul.o snd-seq-virmidi.o +obj-$(CONFIG_SND_EMU10K1_SEQ) += snd-seq-midi-emul.o snd-seq-virmidi.o diff --git a/sound/core/seq/instr/Makefile b/sound/core/seq/instr/Makefile deleted file mode 100644 index 69138f30a29..00000000000 --- a/sound/core/seq/instr/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Makefile for ALSA -# Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz> -# - -snd-ainstr-fm-objs := ainstr_fm.o -snd-ainstr-simple-objs := ainstr_simple.o -snd-ainstr-gf1-objs := ainstr_gf1.o -snd-ainstr-iw-objs := ainstr_iw.o - -# -# this function returns: -# "m" - CONFIG_SND_SEQUENCER is m -# <empty string> - CONFIG_SND_SEQUENCER is undefined -# otherwise parameter #1 value -# -sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) - -# Toplevel Module Dependency -obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-ainstr-fm.o -obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-ainstr-fm.o -obj-$(call sequencer,$(CONFIG_SND_GUS_SYNTH)) += snd-ainstr-gf1.o snd-ainstr-simple.o snd-ainstr-iw.o -obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-ainstr-simple.o diff --git a/sound/core/seq/instr/ainstr_fm.c b/sound/core/seq/instr/ainstr_fm.c deleted file mode 100644 index b09babf272c..00000000000 --- a/sound/core/seq/instr/ainstr_fm.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * FM (OPL2/3) Instrument routines - * Copyright (c) 2000 Uros Bizjak <uros@kss-loka.si> - * - * 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 <sound/driver.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <sound/core.h> -#include <sound/ainstr_fm.h> -#include <sound/initval.h> -#include <asm/uaccess.h> - -MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>"); -MODULE_DESCRIPTION("Advanced Linux Sound Architecture FM Instrument support."); -MODULE_LICENSE("GPL"); - -static int snd_seq_fm_put(void *private_data, struct snd_seq_kinstr *instr, - char __user *instr_data, long len, int atomic, int cmd) -{ - struct fm_instrument *ip; - struct fm_xinstrument ix; - int idx; - - if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE) - return -EINVAL; - /* copy instrument data */ - if (len < (long)sizeof(ix)) - return -EINVAL; - if (copy_from_user(&ix, instr_data, sizeof(ix))) - return -EFAULT; - if (ix.stype != FM_STRU_INSTR) - return -EINVAL; - ip = (struct fm_instrument *)KINSTR_DATA(instr); - ip->share_id[0] = le32_to_cpu(ix.share_id[0]); - ip->share_id[1] = le32_to_cpu(ix.share_id[1]); - ip->share_id[2] = le32_to_cpu(ix.share_id[2]); - ip->share_id[3] = le32_to_cpu(ix.share_id[3]); - ip->type = ix.type; - for (idx = 0; idx < 4; idx++) { - ip->op[idx].am_vib = ix.op[idx].am_vib; - ip->op[idx].ksl_level = ix.op[idx].ksl_level; - ip->op[idx].attack_decay = ix.op[idx].attack_decay; - ip->op[idx].sustain_release = ix.op[idx].sustain_release; - ip->op[idx].wave_select = ix.op[idx].wave_select; - } - for (idx = 0; idx < 2; idx++) { - ip->feedback_connection[idx] = ix.feedback_connection[idx]; - } - ip->echo_delay = ix.echo_delay; - ip->echo_atten = ix.echo_atten; - ip->chorus_spread = ix.chorus_spread; - ip->trnsps = ix.trnsps; - ip->fix_dur = ix.fix_dur; - ip->modes = ix.modes; - ip->fix_key = ix.fix_key; - return 0; -} - -static int snd_seq_fm_get(void *private_data, struct snd_seq_kinstr *instr, - char __user *instr_data, long len, int atomic, - int cmd) -{ - struct fm_instrument *ip; - struct fm_xinstrument ix; - int idx; - - if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL) - return -EINVAL; - if (len < (long)sizeof(ix)) - return -ENOMEM; - memset(&ix, 0, sizeof(ix)); - ip = (struct fm_instrument *)KINSTR_DATA(instr); - ix.stype = FM_STRU_INSTR; - ix.share_id[0] = cpu_to_le32(ip->share_id[0]); - ix.share_id[1] = cpu_to_le32(ip->share_id[1]); - ix.share_id[2] = cpu_to_le32(ip->share_id[2]); - ix.share_id[3] = cpu_to_le32(ip->share_id[3]); - ix.type = ip->type; - for (idx = 0; idx < 4; idx++) { - ix.op[idx].am_vib = ip->op[idx].am_vib; - ix.op[idx].ksl_level = ip->op[idx].ksl_level; - ix.op[idx].attack_decay = ip->op[idx].attack_decay; - ix.op[idx].sustain_release = ip->op[idx].sustain_release; - ix.op[idx].wave_select = ip->op[idx].wave_select; - } - for (idx = 0; idx < 2; idx++) { - ix.feedback_connection[idx] = ip->feedback_connection[idx]; - } - if (copy_to_user(instr_data, &ix, sizeof(ix))) - return -EFAULT; - ix.echo_delay = ip->echo_delay; - ix.echo_atten = ip->echo_atten; - ix.chorus_spread = ip->chorus_spread; - ix.trnsps = ip->trnsps; - ix.fix_dur = ip->fix_dur; - ix.modes = ip->modes; - ix.fix_key = ip->fix_key; - return 0; -} - -static int snd_seq_fm_get_size(void *private_data, struct snd_seq_kinstr *instr, - long *size) -{ - *size = sizeof(struct fm_xinstrument); - return 0; -} - -int snd_seq_fm_init(struct snd_seq_kinstr_ops *ops, - struct snd_seq_kinstr_ops *next) -{ - memset(ops, 0, sizeof(*ops)); - // ops->private_data = private_data; - ops->add_len = sizeof(struct fm_instrument); - 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; - // ops->remove = snd_seq_fm_remove; - // ops->notify = snd_seq_fm_notify; - ops->next = next; - return 0; -} - -/* - * Init part - */ - -static int __init alsa_ainstr_fm_init(void) -{ - return 0; -} - -static void __exit alsa_ainstr_fm_exit(void) -{ -} - -module_init(alsa_ainstr_fm_init) -module_exit(alsa_ainstr_fm_exit) - -EXPORT_SYMBOL(snd_seq_fm_init); diff --git a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c deleted file mode 100644 index 3c31038a74b..00000000000 --- a/sound/core/seq/instr/ainstr_gf1.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * GF1 (GUS) Patch - Instrument routines - * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz> - * - * 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 <sound/driver.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/ainstr_gf1.h> -#include <sound/initval.h> -#include <asm/uaccess.h> - -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); -MODULE_DESCRIPTION("Advanced Linux Sound Architecture GF1 (GUS) Patch support."); -MODULE_LICENSE("GPL"); - -static unsigned int snd_seq_gf1_size(unsigned int size, unsigned int format) -{ - unsigned int result = size; - - if (format & GF1_WAVE_16BIT) - result <<= 1; - if (format & GF1_WAVE_STEREO) - result <<= 1; - return format; -} - -static int snd_seq_gf1_copy_wave_from_stream(struct snd_gf1_ops *ops, - struct gf1_instrument *ip, - char __user **data, - long *len, - int atomic) -{ - struct gf1_wave *wp, *prev; - struct gf1_xwave xp; - int err; - gfp_t gfp_mask; - unsigned int real_size; - - gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; - if (*len < (long)sizeof(xp)) - return -EINVAL; - if (copy_from_user(&xp, *data, sizeof(xp))) - return -EFAULT; - *data += sizeof(xp); - *len -= sizeof(xp); - wp = kzalloc(sizeof(*wp), gfp_mask); - if (wp == NULL) - return -ENOMEM; - wp->share_id[0] = le32_to_cpu(xp.share_id[0]); - wp->share_id[1] = le32_to_cpu(xp.share_id[1]); - wp->share_id[2] = le32_to_cpu(xp.share_id[2]); - wp->share_id[3] = le32_to_cpu(xp.share_id[3]); - wp->format = le32_to_cpu(xp.format); - wp->size = le32_to_cpu(xp.size); - wp->start = le32_to_cpu(xp.start); - wp->loop_start = le32_to_cpu(xp.loop_start); - wp->loop_end = le32_to_cpu(xp.loop_end); - wp->loop_repeat = le16_to_cpu(xp.loop_repeat); - wp->flags = xp.flags; - wp->sample_rate = le32_to_cpu(xp.sample_rate); - wp->low_frequency = le32_to_cpu(xp.low_frequency); - wp->high_frequency = le32_to_cpu(xp.high_frequency); - wp->root_frequency = le32_to_cpu(xp.root_frequency); - wp->tune = le16_to_cpu(xp.tune); - wp->balance = xp.balance; - memcpy(wp->envelope_rate, xp.envelope_rate, 6); - memcpy(wp->envelope_offset, xp.envelope_offset, 6); - wp->tremolo_sweep = xp.tremolo_sweep; - wp->tremolo_rate = xp.tremolo_rate; - wp->tremolo_depth = xp.tremolo_depth; - wp->vibrato_sweep = xp.vibrato_sweep; - wp->vibrato_rate = xp.vibrato_rate; - wp->vibrato_depth = xp.vibrato_depth; - wp->scale_frequency = le16_to_cpu(xp.scale_frequency); - wp->scale_factor = le16_to_cpu(xp.scale_factor); - real_size = snd_seq_gf1_size(wp->size, wp->format); - if ((long)real_size > *len) { - kfree(wp); - return -ENOMEM; - } - if (ops->put_sample) { - err = ops->put_sample(ops->private_data, wp, - *data, real_size, atomic); - if (err < 0) { - kfree(wp); - return err; - } - } - *data += real_size; - *len -= real_size; - prev = ip->wave; - if (prev) { - while (prev->next) prev = prev->next; - prev->next = wp; - } else { - ip->wave = wp; - } - return 0; -} - -static void snd_seq_gf1_wave_free(struct snd_gf1_ops *ops, - struct gf1_wave *wave, - int atomic) -{ - if (ops->remove_sample) - ops->remove_sample(ops->private_data, wave, atomic); - kfree(wave); -} - -static void snd_seq_gf1_instr_free(struct snd_gf1_ops *ops, - struct gf1_instrument *ip, - int atomic) -{ - struct gf1_wave *wave; - - while ((wave = ip->wave) != NULL) { - ip->wave = wave->next; - snd_seq_gf1_wave_free(ops, wave, atomic); - } -} - -static int snd_seq_gf1_put(void *private_data, struct snd_seq_kinstr *instr, - char __user *instr_data, long len, int atomic, - int cmd) -{ - struct snd_gf1_ops *ops = private_data; - struct gf1_instrument *ip; - struct gf1_xinstrument ix; - int err; - gfp_t gfp_mask; - - if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE) - return -EINVAL; - gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; - /* copy instrument data */ - if (len < (long)sizeof(ix)) - return -EINVAL; - if (copy_from_user(&ix, instr_data, sizeof(ix))) - return -EFAULT; - if (ix.stype != GF1_STRU_INSTR) - return -EINVAL; - instr_data += sizeof(ix); - len -= sizeof(ix); - ip = (struct gf1_instrument *)KINSTR_DATA(instr); - ip->exclusion = le16_to_cpu(ix.exclusion); - ip->exclusion_group = le16_to_cpu(ix.exclusion_group); - ip->effect1 = ix.effect1; - ip->effect1_depth = ix.effect1_depth; - ip->effect2 = ix.effect2; - ip->effect2_depth = ix.effect2_depth; - /* copy layers */ - while (len > (long)sizeof(__u32)) { - __u32 stype; - - if (copy_from_user(&stype, instr_data, sizeof(stype))) - return -EFAULT; - if (stype != GF1_STRU_WAVE) { - snd_seq_gf1_instr_free(ops, ip, atomic); - return -EINVAL; - } - err = snd_seq_gf1_copy_wave_from_stream(ops, - ip, - &instr_data, - &len, - atomic); - if (err < 0) { - snd_seq_gf1_instr_free(ops, ip, atomic); - return err; - } - } - return 0; -} - -static int snd_seq_gf1_copy_wave_to_stream(struct snd_gf1_ops *ops, - struct gf1_instrument *ip, - char __user **data, - long *len, - int atomic) -{ - struct gf1_wave *wp; - struct gf1_xwave xp; - int err; - unsigned int real_size; - - for (wp = ip->wave; wp; wp = wp->next) { - if (*len < (long)sizeof(xp)) - return -ENOMEM; - memset(&xp, 0, sizeof(xp)); - xp.stype = GF1_STRU_WAVE; - xp.share_id[0] = cpu_to_le32(wp->share_id[0]); - xp.share_id[1] = cpu_to_le32(wp->share_id[1]); - xp.share_id[2] = cpu_to_le32(wp->share_id[2]); - xp.share_id[3] = cpu_to_le32(wp->share_id[3]); - xp.format = cpu_to_le32(wp->format); - xp.size = cpu_to_le32(wp->size); - xp.start = cpu_to_le32(wp->start); - xp.loop_start = cpu_to_le32(wp->loop_start); - xp.loop_end = cpu_to_le32(wp->loop_end); - xp.loop_repeat = cpu_to_le32(wp->loop_repeat); - xp.flags = wp->flags; - xp.sample_rate = cpu_to_le32(wp->sample_rate); - xp.low_frequency = cpu_to_le32(wp->low_frequency); - xp.high_frequency = cpu_to_le32(wp->high_frequency); - xp.root_frequency = cpu_to_le32(wp->root_frequency); - xp.tune = cpu_to_le16(wp->tune); - xp.balance = wp->balance; - memcpy(xp.envelope_rate, wp->envelope_rate, 6); - memcpy(xp.envelope_offset, wp->envelope_offset, 6); - xp.tremolo_sweep = wp->tremolo_sweep; - xp.tremolo_rate = wp->tremolo_rate; - xp.tremolo_depth = wp->tremolo_depth; - xp.vibrato_sweep = wp->vibrato_sweep; - xp.vibrato_rate = wp->vibrato_rate; - xp.vibrato_depth = wp->vibrato_depth; - xp.scale_frequency = cpu_to_le16(wp->scale_frequency); - xp.scale_factor = cpu_to_le16(wp->scale_factor); - if (copy_to_user(*data, &xp, sizeof(xp))) - return -EFAULT; - *data += sizeof(xp); - *len -= sizeof(xp); - real_size = snd_seq_gf1_size(wp->size, wp->format); - if (*len < (long)real_size) - return -ENOMEM; - if (ops->get_sample) { - err = ops->get_sample(ops->private_data, wp, - *data, real_size, atomic); - if (err < 0) - return err; - } - *data += wp->size; - *len -= wp->size; - } - return 0; -} - -static int snd_seq_gf1_get(void *private_data, struct snd_seq_kinstr *instr, - char __user *instr_data, long len, int atomic, - int cmd) -{ - struct snd_gf1_ops *ops = private_data; - struct gf1_instrument *ip; - struct gf1_xinstrument ix; - - if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL) - return -EINVAL; - if (len < (long)sizeof(ix)) - return -ENOMEM; - memset(&ix, 0, sizeof(ix)); - ip = (struct gf1_instrument *)KINSTR_DATA(instr); - ix.stype = GF1_STRU_INSTR; - ix.exclusion = cpu_to_le16(ip->exclusion); - ix.exclusion_group = cpu_to_le16(ip->exclusion_group); - ix.effect1 = cpu_to_le16(ip->effect1); - ix.effect1_depth = cpu_to_le16(ip->effect1_depth); - ix.effect2 = ip->effect2; - ix.effect2_depth = ip->effect2_depth; - if (copy_to_user(instr_data, &ix, sizeof(ix))) - return -EFAULT; - instr_data += sizeof(ix); - len -= sizeof(ix); - return snd_seq_gf1_copy_wave_to_stream(ops, - ip, - &instr_data, - &len, - atomic); -} - -static int snd_seq_gf1_get_size(void *private_data, struct snd_seq_kinstr *instr, - long *size) -{ - long result; - struct gf1_instrument *ip; - struct gf1_wave *wp; - - *size = 0; - ip = (struct gf1_instrument *)KINSTR_DATA(instr); - result = sizeof(struct gf1_xinstrument); - for (wp = ip->wave; wp; wp = wp->next) { - result += sizeof(struct gf1_xwave); - result += wp->size; - } - *size = result; - return 0; -} - -static int snd_seq_gf1_remove(void *private_data, - struct snd_seq_kinstr *instr, - int atomic) -{ - struct snd_gf1_ops *ops = private_data; - struct gf1_instrument *ip; - - ip = (struct gf1_instrument *)KINSTR_DATA(instr); - snd_seq_gf1_instr_free(ops, ip, atomic); - return 0; -} - -static void snd_seq_gf1_notify(void *private_data, - struct snd_seq_kinstr *instr, - int what) -{ - struct snd_gf1_ops *ops = private_data; - - if (ops->notify) - ops->notify(ops->private_data, instr, what); -} - -int snd_seq_gf1_init(struct snd_gf1_ops *ops, - void *private_data, - struct snd_seq_kinstr_ops *next) -{ - memset(ops, 0, sizeof(*ops)); - ops->private_data = private_data; - ops->kops.private_data = ops; - ops->kops.add_len = sizeof(struct gf1_instrument); - 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; - ops->kops.remove = snd_seq_gf1_remove; - ops->kops.notify = snd_seq_gf1_notify; - ops->kops.next = next; - return 0; -} - -/* - * Init part - */ - -static int __init alsa_ainstr_gf1_init(void) -{ - return 0; -} - -static void __exit alsa_ainstr_gf1_exit(void) -{ -} - -module_init(alsa_ainstr_gf1_init) -module_exit(alsa_ainstr_gf1_exit) - -EXPORT_SYMBOL(snd_seq_gf1_init); diff --git a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c deleted file mode 100644 index 7f8df19ba56..00000000000 --- a/sound/core/seq/instr/ainstr_iw.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * IWFFFF - AMD InterWave (tm) - Instrument routines - * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz> - * - * 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 <sound/driver.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/ainstr_iw.h> -#include <sound/initval.h> -#include <asm/uaccess.h> - -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); -MODULE_DESCRIPTION("Advanced Linux Sound Architecture IWFFFF support."); -MODULE_LICENSE("GPL"); - -static unsigned int snd_seq_iwffff_size(unsigned int size, unsigned int format) -{ - unsigned int result = size; - - if (format & IWFFFF_WAVE_16BIT) - result <<= 1; - if (format & IWFFFF_WAVE_STEREO) - result <<= 1; - return result; -} - -static void snd_seq_iwffff_copy_lfo_from_stream(struct iwffff_lfo *fp, - struct iwffff_xlfo *fx) -{ - fp->freq = le16_to_cpu(fx->freq); - fp->depth = le16_to_cpu(fx->depth); - fp->sweep = le16_to_cpu(fx->sweep); - fp->shape = fx->shape; - fp->delay = fx->delay; -} - -static int snd_seq_iwffff_copy_env_from_stream(__u32 req_stype, - struct iwffff_layer *lp, - struct iwffff_env *ep, - struct iwffff_xenv *ex, - char __user **data, - long *len, - gfp_t gfp_mask) -{ - __u32 stype; - struct iwffff_env_record *rp, *rp_last; - struct iwffff_xenv_record rx; - struct iwffff_env_point *pp; - struct iwffff_xenv_point px; - int points_size, idx; - - ep->flags = ex->flags; - ep->mode = ex->mode; - ep->index = ex->index; - rp_last = NULL; - while (1) { - if (*len < (long)sizeof(__u32)) - return -EINVAL; - if (copy_from_user(&stype, *data, sizeof(stype))) - return -EFAULT; - if (stype == IWFFFF_STRU_WAVE) - return 0; - if (req_stype != stype) { - if (stype == IWFFFF_STRU_ENV_RECP || - stype == IWFFFF_STRU_ENV_RECV) - return 0; - } - if (*len < (long)sizeof(rx)) - return -EINVAL; - if (copy_from_user(&rx, *data, sizeof(rx))) - return -EFAULT; - *data += sizeof(rx); - *len -= sizeof(rx); - points_size = (le16_to_cpu(rx.nattack) + le16_to_cpu(rx.nrelease)) * 2 * sizeof(__u16); - if (points_size > *len) - return -EINVAL; - rp = kzalloc(sizeof(*rp) + points_size, gfp_mask); - if (rp == NULL) - return -ENOMEM; - rp->nattack = le16_to_cpu(rx.nattack); - rp->nrelease = le16_to_cpu(rx.nrelease); - rp->sustain_offset = le16_to_cpu(rx.sustain_offset); - rp->sustain_rate = le16_to_cpu(rx.sustain_rate); - rp->release_rate = le16_to_cpu(rx.release_rate); - rp->hirange = rx.hirange; - pp = (struct iwffff_env_point *)(rp + 1); - for (idx = 0; idx < rp->nattack + rp->nrelease; idx++) { - if (copy_from_user(&px, *data, sizeof(px))) - return -EFAULT; - *data += sizeof(px); - *len -= sizeof(px); - pp->offset = le16_to_cpu(px.offset); - pp->rate = le16_to_cpu(px.rate); - } - if (ep->record == NULL) { - ep->record = rp; - } else { - rp_last = rp; - } - rp_last = rp; - } - return 0; -} - -static int snd_seq_iwffff_copy_wave_from_stream(struct snd_iwffff_ops *ops, - struct iwffff_layer *lp, - char __user **data, - long *len, - int atomic) -{ - struct iwffff_wave *wp, *prev; - struct iwffff_xwave xp; - int err; - gfp_t gfp_mask; - unsigned int real_size; - - gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; - if (*len < (long)sizeof(xp)) - return -EINVAL; - if (copy_from_user(&xp, *data, sizeof(xp))) - return -EFAULT; - *data += sizeof(xp); - *len -= sizeof(xp); - wp = kzalloc(sizeof(*wp), gfp_mask); - if (wp == NULL) - return -ENOMEM; - wp->share_id[0] = le32_to_cpu(xp.share_id[0]); - wp->share_id[1] = le32_to_cpu(xp.share_id[1]); - wp->share_id[2] = le32_to_cpu(xp.share_id[2]); - wp->share_id[3] = le32_to_cpu(xp.share_id[3]); - wp->format = le32_to_cpu(xp.format); - wp->address.memory = le32_to_cpu(xp.offset); - wp->size = le32_to_cpu(xp.size); - wp->start = le32_to_cpu(xp.start); - wp->loop_start = le32_to_cpu(xp.loop_start); - wp->loop_end = le32_to_cpu(xp.loop_end); - wp->loop_repeat = le16_to_cpu(xp.loop_repeat); - wp->sample_ratio = le32_to_cpu(xp.sample_ratio); - wp->attenuation = xp.attenuation; - wp->low_note = xp.low_note; - wp->high_note = xp.high_note; - real_size = snd_seq_iwffff_size(wp->size, wp->format); - if (!(wp->format & IWFFFF_WAVE_ROM)) { - if ((long)real_size > *len) { - kfree(wp); - return -ENOMEM; - } - } - if (ops->put_sample) { - err = ops->put_sample(ops->private_data, wp, - *data, real_size, atomic); - if (err < 0) { - kfree(wp); - return err; - } - } - if (!(wp->format & IWFFFF_WAVE_ROM)) { - *data += real_size; - *len -= real_size; - } - prev = lp->wave; - if (prev) { - while (prev->next) prev = prev->next; - prev->next = wp; - } else { - lp->wave = wp; - } - return 0; -} - -static void snd_seq_iwffff_env_free(struct snd_iwffff_ops *ops, - struct iwffff_env *env, - int atomic) -{ - struct iwffff_env_record *rec; - - while ((rec = env->record) != NULL) { - env->record = rec->next; - kfree(rec); - } -} - -static void snd_seq_iwffff_wave_free(struct snd_iwffff_ops *ops, - struct iwffff_wave *wave, - int atomic) -{ - if (ops->remove_sample) - ops->remove_sample(ops->private_data, wave, atomic); - kfree(wave); -} - -static void snd_seq_iwffff_instr_free(struct snd_iwffff_ops *ops, - struct iwffff_instrument *ip, - int atomic) -{ - struct iwffff_layer *layer; - struct iwffff_wave *wave; - - while ((layer = ip->layer) != NULL) { - ip->layer = layer->next; - snd_seq_iwffff_env_free(ops, &layer->penv, atomic); - snd_seq_iwffff_env_free(ops, &layer->venv, atomic); - while ((wave = layer->wave) != NULL) { - layer->wave = wave->next; - snd_seq_iwffff_wave_free(ops, wave, atomic); - } - kfree(layer); - } -} - -static int snd_seq_iwffff_put(void *private_data, struct snd_seq_kinstr *instr, - char __user *instr_data, long len, int atomic, - int cmd) -{ - struct snd_iwffff_ops *ops = private_data; - struct iwffff_instrument *ip; - struct iwffff_xinstrument ix; - struct iwffff_layer *lp, *prev_lp; - struct iwffff_xlayer lx; - int err; - gfp_t gfp_mask; - - if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE) - return -EINVAL; - gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; - /* copy instrument data */ - if (len < (long)sizeof(ix)) - return -EINVAL; - if (copy_from_user(&ix, instr_data, sizeof(ix))) - return -EFAULT; - if (ix.stype != IWFFFF_STRU_INSTR) - return -EINVAL; - instr_data += sizeof(ix); - len -= sizeof(ix); - ip = (struct iwffff_instrument *)KINSTR_DATA(instr); - ip->exclusion = le16_to_cpu(ix.exclusion); - ip->layer_type = le16_to_cpu(ix.layer_type); - ip->exclusion_group = le16_to_cpu(ix.exclusion_group); - ip->effect1 = ix.effect1; - ip->effect1_depth = ix.effect1_depth; - ip->effect2 = ix.effect2; - ip->effect2_depth = ix.effect2_depth; - /* copy layers */ - prev_lp = NULL; - while (len > 0) { - if (len < (long)sizeof(struct iwffff_xlayer)) { - snd_seq_iwffff_instr_free(ops, ip, atomic); - return -EINVAL; - } - if (copy_from_user(&lx, instr_data, sizeof(lx))) - return -EFAULT; - instr_data += sizeof(lx); - len -= sizeof(lx); - if (lx.stype != IWFFFF_STRU_LAYER) { - snd_seq_iwffff_instr_free(ops, ip, atomic); - return -EINVAL; - } - lp = kzalloc(sizeof(*lp), gfp_mask); - if (lp == NULL) { - snd_seq_iwffff_instr_free(ops, ip, atomic); - return -ENOMEM; - } - if (prev_lp) { - prev_lp->next = lp; - } else { - ip->layer = lp; - } - prev_lp = lp; - lp->flags = lx.flags; - lp->velocity_mode = lx.velocity_mode; - lp->layer_event = lx.layer_event; - lp->low_range = lx.low_range; - lp->high_range = lx.high_range; - lp->pan = lx.pan; - lp->pan_freq_scale = lx.pan_freq_scale; - lp->attenuation = lx.attenuation; - snd_seq_iwffff_copy_lfo_from_stream(&lp->tremolo, &lx.tremolo); - snd_seq_iwffff_copy_lfo_from_stream(&lp->vibrato, &lx.vibrato); - lp->freq_scale = le16_to_cpu(lx.freq_scale); - lp->freq_center = lx.freq_center; - err = snd_seq_iwffff_copy_env_from_stream(IWFFFF_STRU_ENV_RECP, - lp, - &lp->penv, &lx.penv, - &instr_data, &len, - gfp_mask); - if (err < 0) { - snd_seq_iwffff_instr_free(ops, ip, atomic); - return err; - } - err = snd_seq_iwffff_copy_env_from_stream(IWFFFF_STRU_ENV_RECV, - lp, - &lp->venv, &lx.venv, - &instr_data, &len, - gfp_mask); - if (err < 0) { - snd_seq_iwffff_instr_free(ops, ip, atomic); - return err; - } - while (len > (long)sizeof(__u32)) { - __u32 stype; - - if (copy_from_user(&stype, instr_data, sizeof(stype))) - return -EFAULT; - if (stype != IWFFFF_STRU_WAVE) - break; - err = snd_seq_iwffff_copy_wave_from_stream(ops, - lp, - &instr_data, - &len, - atomic); - if (err < 0) { - snd_seq_iwffff_instr_free(ops, ip, atomic); - return err; - } - } - } - return 0; -} - -static void snd_seq_iwffff_copy_lfo_to_stream(struct iwffff_xlfo *fx, - struct iwffff_lfo *fp) -{ - fx->freq = cpu_to_le16(fp->freq); - fx->depth = cpu_to_le16(fp->depth); - fx->sweep = cpu_to_le16(fp->sweep); - fp->shape = fx->shape; - fp->delay = fx->delay; -} - -static int snd_seq_iwffff_copy_env_to_stream(__u32 req_stype, - struct iwffff_layer *lp, - struct iwffff_xenv *ex, - struct iwffff_env *ep, - char __user **data, - long *len) -{ - struct iwffff_env_record *rp; - struct iwffff_xenv_record rx; - struct iwffff_env_point *pp; - struct iwffff_xenv_point px; - int points_size, idx; - - ex->flags = ep->flags; - ex->mode = ep->mode; - ex->index = ep->index; - for (rp = ep->record; rp; rp = rp->next) { - if (*len < (long)sizeof(rx)) - return -ENOMEM; - memset(&rx, 0, sizeof(rx)); - rx.stype = req_stype; - rx.nattack = cpu_to_le16(rp->nattack); - rx.nrelease = cpu_to_le16(rp->nrelease); - rx.sustain_offset = cpu_to_le16(rp->sustain_offset); - rx.sustain_rate = cpu_to_le16(rp->sustain_rate); - rx.release_rate = cpu_to_le16(rp->release_rate); - rx.hirange = cpu_to_le16(rp->hirange); - if (copy_to_user(*data, &rx, sizeof(rx))) - return -EFAULT; - *data += sizeof(rx); - *len -= sizeof(rx); - points_size = (rp->nattack + rp->nrelease) * 2 * sizeof(__u16); - if (*len < points_size) - return -ENOMEM; - pp = (struct iwffff_env_point *)(rp + 1); - for (idx = 0; idx < rp->nattack + rp->nrelease; idx++) { - px.offset = cpu_to_le16(pp->offset); - px.rate = cpu_to_le16(pp->rate); - if (copy_to_user(*data, &px, sizeof(px))) - return -EFAULT; - *data += sizeof(px); - *len -= sizeof(px); - } - } - return 0; -} - -static int snd_seq_iwffff_copy_wave_to_stream(struct snd_iwffff_ops *ops, - struct iwffff_layer *lp, - char __user **data, - long *len, - int atomic) -{ - struct iwffff_wave *wp; - struct iwffff_xwave xp; - int err; - unsigned int real_size; - - for (wp = lp->wave; wp; wp = wp->next) { - if (*len < (long)sizeof(xp)) - return -ENOMEM; - memset(&xp, 0, sizeof(xp)); - xp.stype = IWFFFF_STRU_WAVE; - xp.share_id[0] = cpu_to_le32(wp->share_id[0]); - xp.share_id[1] = cpu_to_le32(wp->share_id[1]); - xp.share_id[2] = cpu_to_le32(wp->share_id[2]); - xp.share_id[3] = cpu_to_le32(wp->share_id[3]); - xp.format = cpu_to_le32(wp->format); - if (wp->format & IWFFFF_WAVE_ROM) - xp.offset = cpu_to_le32(wp->address.memory); - xp.size = cpu_to_le32(wp->size); - xp.start = cpu_to_le32(wp->start); - xp.loop_start = cpu_to_le32(wp->loop_start); - xp.loop_end = cpu_to_le32(wp->loop_end); - xp.loop_repeat = cpu_to_le32(wp->loop_repeat); - xp.sample_ratio = cpu_to_le32(wp->sample_ratio); - xp.attenuation = wp->attenuation; - xp.low_note = wp->low_note; - xp.high_note = wp->high_note; - if (copy_to_user(*data, &xp, sizeof(xp))) - return -EFAULT; - *data += sizeof(xp); - *len -= sizeof(xp); - real_size = snd_seq_iwffff_size(wp->size, wp->format); - if (!(wp->format & IWFFFF_WAVE_ROM)) { - if (*len < (long)real_size) - return -ENOMEM; - } - if (ops->get_sample) { - err = ops->get_sample(ops->private_data, wp, - *data, real_size, atomic); - if (err < 0) - return err; - } - if (!(wp->format & IWFFFF_WAVE_ROM)) { - *data += real_size; - *len -= real_size; - } - } - return 0; -} - -static int snd_seq_iwffff_get(void *private_data, struct snd_seq_kinstr *instr, - char __user *instr_data, long len, int atomic, int cmd) -{ - struct snd_iwffff_ops *ops = private_data; - struct iwffff_instrument *ip; - struct iwffff_xinstrument ix; - struct iwffff_layer *lp; - struct iwffff_xlayer lx; - char __user *layer_instr_data; - int err; - - if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL) - return -EINVAL; - if (len < (long)sizeof(ix)) - return -ENOMEM; - memset(&ix, 0, sizeof(ix)); - ip = (struct iwffff_instrument *)KINSTR_DATA(instr); - ix.stype = IWFFFF_STRU_INSTR; - ix.exclusion = cpu_to_le16(ip->exclusion); - ix.layer_type = cpu_to_le16(ip->layer_type); - ix.exclusion_group = cpu_to_le16(ip->exclusion_group); - ix.effect1 = cpu_to_le16(ip->effect1); - ix.effect1_depth = cpu_to_le16(ip->effect1_depth); - ix.effect2 = ip->effect2; - ix.effect2_depth = ip->effect2_depth; - if (copy_to_user(instr_data, &ix, sizeof(ix))) - return -EFAULT; - instr_data += sizeof(ix); - len -= sizeof(ix); - for (lp = ip->layer; lp; lp = lp->next) { - if (len < (long)sizeof(lx)) - return -ENOMEM; - memset(&lx, 0, sizeof(lx)); - lx.stype = IWFFFF_STRU_LAYER; - lx.flags = lp->flags; - lx.velocity_mode = lp->velocity_mode; - lx.layer_event = lp->layer_event; - lx.low_range = lp->low_range; - lx.high_range = lp->high_range; - lx.pan = lp->pan; - lx.pan_freq_scale = lp->pan_freq_scale; - lx.attenuation = lp->attenuation; - snd_seq_iwffff_copy_lfo_to_stream(&lx.tremolo, &lp->tremolo); - snd_seq_iwffff_copy_lfo_to_stream(&lx.vibrato, &lp->vibrato); - layer_instr_data = instr_data; - instr_data += sizeof(lx); - len -= sizeof(lx); - err = snd_seq_iwffff_copy_env_to_stream(IWFFFF_STRU_ENV_RECP, - lp, - &lx.penv, &lp->penv, - &instr_data, &len); - if (err < 0) - return err; - err = snd_seq_iwffff_copy_env_to_stream(IWFFFF_STRU_ENV_RECV, - lp, - &lx.venv, &lp->venv, - &instr_data, &len); - if (err < 0) - return err; - /* layer structure updating is now finished */ - if (copy_to_user(layer_instr_data, &lx, sizeof(lx))) - return -EFAULT; - err = snd_seq_iwffff_copy_wave_to_stream(ops, - lp, - &instr_data, - &len, - atomic); - if (err < 0) - return err; - } - return 0; -} - -static long snd_seq_iwffff_env_size_in_stream(struct iwffff_env *ep) -{ - long result = 0; - struct iwffff_env_record *rp; - - for (rp = ep->record; rp; rp = rp->next) { - result += sizeof(struct iwffff_xenv_record); - result += (rp->nattack + rp->nrelease) * 2 * sizeof(__u16); - } - return 0; -} - -static long snd_seq_iwffff_wave_size_in_stream(struct iwffff_layer *lp) -{ - long result = 0; - struct iwffff_wave *wp; - - for (wp = lp->wave; wp; wp = wp->next) { - result += sizeof(struct iwffff_xwave); - if (!(wp->format & IWFFFF_WAVE_ROM)) - result += wp->size; - } - return result; -} - -static int snd_seq_iwffff_get_size(void *private_data, struct snd_seq_kinstr *instr, - long *size) -{ - long result; - struct iwffff_instrument *ip; - struct iwffff_layer *lp; - - *size = 0; - ip = (struct iwffff_instrument *)KINSTR_DATA(instr); - result = sizeof(struct iwffff_xinstrument); - for (lp = ip->layer; lp; lp = lp->next) { - result += sizeof(struct iwffff_xlayer); - result += snd_seq_iwffff_env_size_in_stream(&lp->penv); - result += snd_seq_iwffff_env_size_in_stream(&lp->venv); - result += snd_seq_iwffff_wave_size_in_stream(lp); - } - *size = result; - return 0; -} - -static int snd_seq_iwffff_remove(void *private_data, - struct snd_seq_kinstr *instr, - int atomic) -{ - struct snd_iwffff_ops *ops = private_data; - struct iwffff_instrument *ip; - - ip = (struct iwffff_instrument *)KINSTR_DATA(instr); - snd_seq_iwffff_instr_free(ops, ip, atomic); - return 0; -} - -static void snd_seq_iwffff_notify(void *private_data, - struct snd_seq_kinstr *instr, - int what) -{ - struct snd_iwffff_ops *ops = private_data; - - if (ops->notify) - ops->notify(ops->private_data, instr, what); -} - -int snd_seq_iwffff_init(struct snd_iwffff_ops *ops, - void *private_data, - struct snd_seq_kinstr_ops *next) -{ - memset(ops, 0, sizeof(*ops)); - ops->private_data = private_data; - ops->kops.private_data = ops; - ops->kops.add_len = sizeof(struct iwffff_instrument); - 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; - ops->kops.remove = snd_seq_iwffff_remove; - ops->kops.notify = snd_seq_iwffff_notify; - ops->kops.next = next; - return 0; -} - -/* - * Init part - */ - -static int __init alsa_ainstr_iw_init(void) -{ - return 0; -} - -static void __exit alsa_ainstr_iw_exit(void) -{ -} - -module_init(alsa_ainstr_iw_init) -module_exit(alsa_ainstr_iw_exit) - -EXPORT_SYMBOL(snd_seq_iwffff_init); diff --git a/sound/core/seq/instr/ainstr_simple.c b/sound/core/seq/instr/ainstr_simple.c deleted file mode 100644 index 6d6ffece7cb..00000000000 --- a/sound/core/seq/instr/ainstr_simple.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Simple (MOD player) - Instrument routines - * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz> - * - * 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 <sound/driver.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/ainstr_simple.h> -#include <sound/initval.h> -#include <asm/uaccess.h> - -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); -MODULE_DESCRIPTION("Advanced Linux Sound Architecture Simple Instrument support."); -MODULE_LICENSE("GPL"); - -static unsigned int snd_seq_simple_size(unsigned int size, unsigned int format) -{ - unsigned int result = size; - - if (format & SIMPLE_WAVE_16BIT) - result <<= 1; - if (format & SIMPLE_WAVE_STEREO) - result <<= 1; - return result; -} - -static void snd_seq_simple_instr_free(struct snd_simple_ops *ops, - struct simple_instrument *ip, - int atomic) -{ - if (ops->remove_sample) - ops->remove_sample(ops->private_data, ip, atomic); -} - -static int snd_seq_simple_put(void *private_data, struct snd_seq_kinstr *instr, - char __user *instr_data, long len, - int atomic, int cmd) -{ - struct snd_simple_ops *ops = private_data; - struct simple_instrument *ip; - struct simple_xinstrument ix; - int err; - gfp_t gfp_mask; - unsigned int real_size; - - if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE) - return -EINVAL; - gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; - /* copy instrument data */ - if (len < (long)sizeof(ix)) - return -EINVAL; - if (copy_from_user(&ix, instr_data, sizeof(ix))) - return -EFAULT; - if (ix.stype != SIMPLE_STRU_INSTR) - return -EINVAL; - instr_data += sizeof(ix); - len -= sizeof(ix); - ip = (struct simple_instrument *)KINSTR_DATA(instr); - ip->share_id[0] = le32_to_cpu(ix.share_id[0]); - ip->share_id[1] = le32_to_cpu(ix.share_id[1]); - ip->share_id[2] = le32_to_cpu(ix.share_id[2]); - ip->share_id[3] = le32_to_cpu(ix.share_id[3]); - ip->format = le32_to_cpu(ix.format); - ip->size = le32_to_cpu(ix.size); - ip->start = le32_to_cpu(ix.start); - ip->loop_start = le32_to_cpu(ix.loop_start); - ip->loop_end = le32_to_cpu(ix.loop_end); - ip->loop_repeat = le16_to_cpu(ix.loop_repeat); - ip->effect1 = ix.effect1; - ip->effect1_depth = ix.effect1_depth; - ip->effect2 = ix.effect2; - ip->effect2_depth = ix.effect2_depth; - real_size = snd_seq_simple_size(ip->size, ip->format); - if (len < (long)real_size) - return -EINVAL; - if (ops->put_sample) { - err = ops->put_sample(ops->private_data, ip, - instr_data, real_size, atomic); - if (err < 0) - return err; - } - return 0; -} - -static int snd_seq_simple_get(void *private_data, struct snd_seq_kinstr *instr, - char __user *instr_data, long len, - int atomic, int cmd) -{ - struct snd_simple_ops *ops = private_data; - struct simple_instrument *ip; - struct simple_xinstrument ix; - int err; - unsigned int real_size; - - if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL) - return -EINVAL; - if (len < (long)sizeof(ix)) - return -ENOMEM; - memset(&ix, 0, sizeof(ix)); - ip = (struct simple_instrument *)KINSTR_DATA(instr); - ix.stype = SIMPLE_STRU_INSTR; - ix.share_id[0] = cpu_to_le32(ip->share_id[0]); - ix.share_id[1] = cpu_to_le32(ip->share_id[1]); - ix.share_id[2] = cpu_to_le32(ip->share_id[2]); - ix.share_id[3] = cpu_to_le32(ip->share_id[3]); - ix.format = cpu_to_le32(ip->format); - ix.size = cpu_to_le32(ip->size); - ix.start = cpu_to_le32(ip->start); - ix.loop_start = cpu_to_le32(ip->loop_start); - ix.loop_end = cpu_to_le32(ip->loop_end); - ix.loop_repeat = cpu_to_le32(ip->loop_repeat); - ix.effect1 = cpu_to_le16(ip->effect1); - ix.effect1_depth = cpu_to_le16(ip->effect1_depth); - ix.effect2 = ip->effect2; - ix.effect2_depth = ip->effect2_depth; - if (copy_to_user(instr_data, &ix, sizeof(ix))) - return -EFAULT; - instr_data += sizeof(ix); - len -= sizeof(ix); - real_size = snd_seq_simple_size(ip->size, ip->format); - if (len < (long)real_size) - return -ENOMEM; - if (ops->get_sample) { - err = ops->get_sample(ops->private_data, ip, - instr_data, real_size, atomic); - if (err < 0) - return err; - } - return 0; -} - -static int snd_seq_simple_get_size(void *private_data, struct snd_seq_kinstr *instr, - long *size) -{ - struct simple_instrument *ip; - - ip = (struct simple_instrument *)KINSTR_DATA(instr); - *size = sizeof(struct simple_xinstrument) + snd_seq_simple_size(ip->size, ip->format); - return 0; -} - -static int snd_seq_simple_remove(void *private_data, - struct snd_seq_kinstr *instr, - int atomic) -{ - struct snd_simple_ops *ops = private_data; - struct simple_instrument *ip; - - ip = (struct simple_instrument *)KINSTR_DATA(instr); - snd_seq_simple_instr_free(ops, ip, atomic); - return 0; -} - -static void snd_seq_simple_notify(void *private_data, - struct snd_seq_kinstr *instr, - int what) -{ - struct snd_simple_ops *ops = private_data; - - if (ops->notify) - ops->notify(ops->private_data, instr, what); -} - -int snd_seq_simple_init(struct snd_simple_ops *ops, - void *private_data, - struct snd_seq_kinstr_ops *next) -{ - memset(ops, 0, sizeof(*ops)); - ops->private_data = private_data; - ops->kops.private_data = ops; - ops->kops.add_len = sizeof(struct simple_instrument); - 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; - ops->kops.remove = snd_seq_simple_remove; - ops->kops.notify = snd_seq_simple_notify; - ops->kops.next = next; - return 0; -} - -/* - * Init part - */ - -static int __init alsa_ainstr_simple_init(void) -{ - return 0; -} - -static void __exit alsa_ainstr_simple_exit(void) -{ -} - -module_init(alsa_ainstr_simple_init) -module_exit(alsa_ainstr_simple_exit) - -EXPORT_SYMBOL(snd_seq_simple_init); diff --git a/sound/core/seq/oss/Makefile b/sound/core/seq/oss/Makefile index a37ddedf710..b38406b8463 100644 --- a/sound/core/seq/oss/Makefile +++ b/sound/core/seq/oss/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz> +# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz> # snd-seq-oss-objs := seq_oss.o seq_oss_init.o seq_oss_timer.o seq_oss_ioctl.o \ diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c index c98f0ba1381..16d42679e43 100644 --- a/sound/core/seq/oss/seq_oss.c +++ b/sound/core/seq/oss/seq_oss.c @@ -20,10 +20,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <sound/driver.h> #include <linux/init.h> -#include <linux/smp_lock.h> -#include <linux/moduleparam.h> +#include <linux/module.h> +#include <linux/mutex.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/initval.h> @@ -40,12 +39,6 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_SEQUENCER); MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_MUSIC); -#ifdef SNDRV_SEQ_OSS_DEBUG -module_param(seq_oss_debug, int, 0644); -MODULE_PARM_DESC(seq_oss_debug, "debug option"); -int seq_oss_debug = 0; -#endif - /* * prototypes @@ -124,7 +117,7 @@ module_exit(alsa_seq_oss_exit) * ALSA minor device interface */ -static DECLARE_MUTEX(register_mutex); +static DEFINE_MUTEX(register_mutex); static int odev_open(struct inode *inode, struct file *file) @@ -136,9 +129,9 @@ odev_open(struct inode *inode, struct file *file) else level = SNDRV_SEQ_OSS_MODE_SYNTH; - down(®ister_mutex); + mutex_lock(®ister_mutex); rc = snd_seq_oss_open(file, level); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return rc; } @@ -153,9 +146,9 @@ odev_release(struct inode *inode, struct file *file) snd_seq_oss_drain_write(dp); - down(®ister_mutex); + mutex_lock(®ister_mutex); snd_seq_oss_release(dp); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } @@ -165,7 +158,8 @@ odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { struct seq_oss_devinfo *dp; dp = file->private_data; - snd_assert(dp != NULL, return -EIO); + if (snd_BUG_ON(!dp)) + return -ENXIO; return snd_seq_oss_read(dp, buf, count); } @@ -175,7 +169,8 @@ odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offs { struct seq_oss_devinfo *dp; dp = file->private_data; - snd_assert(dp != NULL, return -EIO); + if (snd_BUG_ON(!dp)) + return -ENXIO; return snd_seq_oss_write(dp, buf, count, file); } @@ -184,7 +179,8 @@ odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct seq_oss_devinfo *dp; dp = file->private_data; - snd_assert(dp != NULL, return -EIO); + if (snd_BUG_ON(!dp)) + return -ENXIO; return snd_seq_oss_ioctl(dp, cmd, arg); } @@ -199,7 +195,8 @@ odev_poll(struct file *file, poll_table * wait) { struct seq_oss_devinfo *dp; dp = file->private_data; - snd_assert(dp != NULL, return 0); + if (snd_BUG_ON(!dp)) + return -ENXIO; return snd_seq_oss_poll(dp, file, wait); } @@ -207,7 +204,7 @@ odev_poll(struct file *file, poll_table * wait) * registration of sequencer minor device */ -static struct file_operations seq_oss_f_ops = +static const struct file_operations seq_oss_f_ops = { .owner = THIS_MODULE, .read = odev_read, @@ -217,6 +214,7 @@ static struct file_operations seq_oss_f_ops = .poll = odev_poll, .unlocked_ioctl = odev_ioctl, .compat_ioctl = odev_ioctl_compat, + .llseek = noop_llseek, }; static int __init @@ -224,39 +222,35 @@ register_device(void) { int rc; - down(®ister_mutex); + mutex_lock(®ister_mutex); if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0, - &seq_oss_f_ops, NULL, - SNDRV_SEQ_OSS_DEVNAME)) < 0) { - snd_printk(KERN_ERR "can't register device seq\n"); - up(®ister_mutex); + &seq_oss_f_ops, NULL)) < 0) { + pr_err("ALSA: seq_oss: can't register device seq\n"); + mutex_unlock(®ister_mutex); return rc; } if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0, - &seq_oss_f_ops, NULL, - SNDRV_SEQ_OSS_DEVNAME)) < 0) { - snd_printk(KERN_ERR "can't register device music\n"); + &seq_oss_f_ops, NULL)) < 0) { + pr_err("ALSA: seq_oss: can't register device music\n"); snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return rc; } - debug_printk(("device registered\n")); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } static void unregister_device(void) { - down(®ister_mutex); - debug_printk(("device unregistered\n")); + mutex_lock(®ister_mutex); if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0) - snd_printk(KERN_ERR "error unregister device music\n"); + pr_err("ALSA: seq_oss: error unregister device music\n"); if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0) < 0) - snd_printk(KERN_ERR "error unregister device seq\n"); - up(®ister_mutex); + pr_err("ALSA: seq_oss: error unregister device seq\n"); + mutex_unlock(®ister_mutex); } /* @@ -270,12 +264,12 @@ static struct snd_info_entry *info_entry; static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buf) { - down(®ister_mutex); + mutex_lock(®ister_mutex); snd_iprintf(buf, "OSS sequencer emulation version %s\n", SNDRV_SEQ_OSS_VERSION_STR); snd_seq_oss_system_info_read(buf); snd_seq_oss_synth_info_read(buf); snd_seq_oss_midi_info_read(buf); - up(®ister_mutex); + mutex_unlock(®ister_mutex); } @@ -290,7 +284,6 @@ register_proc(void) entry->content = SNDRV_INFO_CONTENT_TEXT; entry->private_data = NULL; - entry->c.text.read_size = 1024; entry->c.text.read = info_read; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); @@ -303,8 +296,7 @@ register_proc(void) static void unregister_proc(void) { - if (info_entry) - snd_info_unregister(info_entry); + snd_info_free_entry(info_entry); info_entry = NULL; } #endif /* CONFIG_PROC_FS */ diff --git a/sound/core/seq/oss/seq_oss_device.h b/sound/core/seq/oss/seq_oss_device.h index 9a8567c928e..b4392432524 100644 --- a/sound/core/seq/oss/seq_oss_device.h +++ b/sound/core/seq/oss/seq_oss_device.h @@ -21,7 +21,6 @@ #ifndef __SEQ_OSS_DEVICE_H #define __SEQ_OSS_DEVICE_H -#include <sound/driver.h> #include <linux/time.h> #include <linux/wait.h> #include <linux/slab.h> @@ -32,9 +31,6 @@ #include <sound/seq_kernel.h> #include <sound/info.h> -/* enable debug print */ -#define SNDRV_SEQ_OSS_DEBUG - /* max. applications */ #define SNDRV_SEQ_OSS_MAX_CLIENTS 16 #define SNDRV_SEQ_OSS_MAX_SYNTH_DEVS 16 @@ -47,7 +43,6 @@ #define SNDRV_SEQ_OSS_VERSION_STR "0.1.8" /* device and proc interface name */ -#define SNDRV_SEQ_OSS_DEVNAME "seq_oss" #define SNDRV_SEQ_OSS_PROCNAME "oss" @@ -178,13 +173,4 @@ snd_seq_oss_fill_addr(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, /* misc. functions for proc interface */ char *enabled_str(int bool); - -/* for debug */ -#ifdef SNDRV_SEQ_OSS_DEBUG -extern int seq_oss_debug; -#define debug_printk(x) do { if (seq_oss_debug > 0) snd_printk x; } while (0) -#else -#define debug_printk(x) /**/ -#endif - #endif /* __SEQ_OSS_DEVICE_H */ diff --git a/sound/core/seq/oss/seq_oss_event.c b/sound/core/seq/oss/seq_oss_event.c index 066f5f3e3f4..c3908862bc8 100644 --- a/sound/core/seq/oss/seq_oss_event.c +++ b/sound/core/seq/oss/seq_oss_event.c @@ -285,7 +285,12 @@ local_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev static int note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev) { - struct seq_oss_synthinfo *info = &dp->synths[dev]; + struct seq_oss_synthinfo *info; + + if (!snd_seq_oss_synth_is_valid(dp, dev)) + return -ENXIO; + + info = &dp->synths[dev]; switch (info->arg.event_passing) { case SNDRV_SEQ_OSS_PROCESS_EVENTS: if (! info->ch || ch < 0 || ch >= info->nr_voices) { @@ -340,7 +345,12 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st static int note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev) { - struct seq_oss_synthinfo *info = &dp->synths[dev]; + struct seq_oss_synthinfo *info; + + if (!snd_seq_oss_synth_is_valid(dp, dev)) + return -ENXIO; + + info = &dp->synths[dev]; switch (info->arg.event_passing) { case SNDRV_SEQ_OSS_PROCESS_EVENTS: if (! info->ch || ch < 0 || ch >= info->nr_voices) { diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c index ca5a2ed4d7c..b9184d20c39 100644 --- a/sound/core/seq/oss/seq_oss_init.c +++ b/sound/core/seq/oss/seq_oss_init.c @@ -28,7 +28,10 @@ #include "seq_oss_timer.h" #include "seq_oss_event.h" #include <linux/init.h> +#include <linux/export.h> #include <linux/moduleparam.h> +#include <linux/slab.h> +#include <linux/workqueue.h> /* * common variables @@ -58,6 +61,14 @@ static void free_devinfo(void *private); #define call_ctl(type,rec) snd_seq_kernel_client_ctl(system_client, type, rec) +/* call snd_seq_oss_midi_lookup_ports() asynchronously */ +static void async_call_lookup_ports(struct work_struct *work) +{ + snd_seq_oss_midi_lookup_ports(system_client); +} + +static DECLARE_WORK(async_lookup_work, async_call_lookup_ports); + /* * create sequencer client for OSS sequencer */ @@ -81,10 +92,6 @@ snd_seq_oss_create_client(void) goto __error; system_client = rc; - debug_printk(("new client = %d\n", rc)); - - /* look up midi devices */ - snd_seq_oss_midi_lookup_ports(system_client); /* create annoucement receiver port */ memset(port, 0, sizeof(*port)); @@ -113,6 +120,9 @@ snd_seq_oss_create_client(void) } rc = 0; + /* look up midi devices */ + schedule_work(&async_lookup_work); + __error: kfree(port); return rc; @@ -158,6 +168,7 @@ receive_announce(struct snd_seq_event *ev, int direct, void *private, int atomic int snd_seq_oss_delete_client(void) { + cancel_work_sync(&async_lookup_work); if (system_client >= 0) snd_seq_delete_kernel_client(system_client); @@ -176,49 +187,48 @@ snd_seq_oss_open(struct file *file, int level) int i, rc; struct seq_oss_devinfo *dp; - if ((dp = kzalloc(sizeof(*dp), GFP_KERNEL)) == NULL) { - snd_printk(KERN_ERR "can't malloc device info\n"); + dp = kzalloc(sizeof(*dp), GFP_KERNEL); + if (!dp) { + pr_err("ALSA: seq_oss: can't malloc device info\n"); return -ENOMEM; } - debug_printk(("oss_open: dp = %p\n", dp)); + + dp->cseq = system_client; + dp->port = -1; + dp->queue = -1; for (i = 0; i < SNDRV_SEQ_OSS_MAX_CLIENTS; i++) { if (client_table[i] == NULL) break; } - if (i >= SNDRV_SEQ_OSS_MAX_CLIENTS) { - snd_printk(KERN_ERR "too many applications\n"); - kfree(dp); - return -ENOMEM; - } dp->index = i; - dp->cseq = system_client; - dp->port = -1; - dp->queue = -1; - dp->readq = NULL; - dp->writeq = NULL; + if (i >= SNDRV_SEQ_OSS_MAX_CLIENTS) { + pr_err("ALSA: seq_oss: too many applications\n"); + rc = -ENOMEM; + goto _error; + } /* look up synth and midi devices */ snd_seq_oss_synth_setup(dp); snd_seq_oss_midi_setup(dp); if (dp->synth_opened == 0 && dp->max_mididev == 0) { - /* snd_printk(KERN_ERR "no device found\n"); */ + /* pr_err("ALSA: seq_oss: no device found\n"); */ rc = -ENODEV; goto _error; } /* create port */ - debug_printk(("create new port\n")); - if ((rc = create_port(dp)) < 0) { - snd_printk(KERN_ERR "can't create port\n"); + rc = create_port(dp); + if (rc < 0) { + pr_err("ALSA: seq_oss: can't create port\n"); goto _error; } /* allocate queue */ - debug_printk(("allocate queue\n")); - if ((rc = alloc_seq_queue(dp)) < 0) + rc = alloc_seq_queue(dp); + if (rc < 0) goto _error; /* set address */ @@ -233,32 +243,30 @@ snd_seq_oss_open(struct file *file, int level) dp->file_mode = translate_mode(file); /* initialize read queue */ - debug_printk(("initialize read queue\n")); if (is_read_mode(dp->file_mode)) { - if ((dp->readq = snd_seq_oss_readq_new(dp, maxqlen)) == NULL) { + dp->readq = snd_seq_oss_readq_new(dp, maxqlen); + if (!dp->readq) { rc = -ENOMEM; goto _error; } } /* initialize write queue */ - debug_printk(("initialize write queue\n")); if (is_write_mode(dp->file_mode)) { dp->writeq = snd_seq_oss_writeq_new(dp, maxqlen); - if (dp->writeq == NULL) { + if (!dp->writeq) { rc = -ENOMEM; goto _error; } } /* initialize timer */ - debug_printk(("initialize timer\n")); - if ((dp->timer = snd_seq_oss_timer_new(dp)) == NULL) { - snd_printk(KERN_ERR "can't alloc timer\n"); + dp->timer = snd_seq_oss_timer_new(dp); + if (!dp->timer) { + pr_err("ALSA: seq_oss: can't alloc timer\n"); rc = -ENOMEM; goto _error; } - debug_printk(("timer initialized\n")); /* set private data pointer */ file->private_data = dp; @@ -272,15 +280,13 @@ snd_seq_oss_open(struct file *file, int level) client_table[dp->index] = dp; num_clients++; - debug_printk(("open done\n")); return 0; _error: snd_seq_oss_synth_cleanup(dp); snd_seq_oss_midi_cleanup(dp); - i = dp->queue; + delete_seq_queue(dp->queue); delete_port(dp); - delete_seq_queue(i); return rc; } @@ -332,7 +338,6 @@ create_port(struct seq_oss_devinfo *dp) return rc; dp->port = port.addr.port; - debug_printk(("new port = %d\n", port.addr.port)); return 0; } @@ -343,10 +348,11 @@ create_port(struct seq_oss_devinfo *dp) static int delete_port(struct seq_oss_devinfo *dp) { - if (dp->port < 0) + if (dp->port < 0) { + kfree(dp); return 0; + } - debug_printk(("delete_port %i\n", dp->port)); return snd_seq_event_port_detach(dp->cseq, dp->port); } @@ -384,7 +390,7 @@ delete_seq_queue(int queue) qinfo.queue = queue; rc = call_ctl(SNDRV_SEQ_IOCTL_DELETE_QUEUE, &qinfo); if (rc < 0) - printk(KERN_ERR "seq-oss: unable to delete queue %d (%d)\n", queue, rc); + pr_err("ALSA: seq_oss: unable to delete queue %d (%d)\n", queue, rc); return rc; } @@ -421,21 +427,16 @@ snd_seq_oss_release(struct seq_oss_devinfo *dp) client_table[dp->index] = NULL; num_clients--; - debug_printk(("resetting..\n")); snd_seq_oss_reset(dp); - debug_printk(("cleaning up..\n")); snd_seq_oss_synth_cleanup(dp); snd_seq_oss_midi_cleanup(dp); /* clear slot */ - debug_printk(("releasing resource..\n")); queue = dp->queue; if (dp->port >= 0) delete_port(dp); delete_seq_queue(queue); - - debug_printk(("release done\n")); } @@ -449,7 +450,6 @@ snd_seq_oss_drain_write(struct seq_oss_devinfo *dp) return; if (is_write_mode(dp->file_mode) && !is_nonblock_mode(dp->file_mode) && dp->writeq) { - debug_printk(("syncing..\n")); while (snd_seq_oss_writeq_sync(dp->writeq)) ; } diff --git a/sound/core/seq/oss/seq_oss_ioctl.c b/sound/core/seq/oss/seq_oss_ioctl.c index 5ac701c903c..5b8520177b0 100644 --- a/sound/core/seq/oss/seq_oss_ioctl.c +++ b/sound/core/seq/oss/seq_oss_ioctl.c @@ -90,12 +90,10 @@ snd_seq_oss_ioctl(struct seq_oss_devinfo *dp, unsigned int cmd, unsigned long ca return snd_seq_oss_timer_ioctl(dp->timer, cmd, arg); case SNDCTL_SEQ_PANIC: - debug_printk(("panic\n")); snd_seq_oss_reset(dp); return -EINVAL; case SNDCTL_SEQ_SYNC: - debug_printk(("sync\n")); if (! is_write_mode(dp->file_mode) || dp->writeq == NULL) return 0; while (snd_seq_oss_writeq_sync(dp->writeq)) @@ -105,55 +103,45 @@ snd_seq_oss_ioctl(struct seq_oss_devinfo *dp, unsigned int cmd, unsigned long ca return 0; case SNDCTL_SEQ_RESET: - debug_printk(("reset\n")); snd_seq_oss_reset(dp); return 0; case SNDCTL_SEQ_TESTMIDI: - debug_printk(("test midi\n")); if (get_user(dev, p)) return -EFAULT; return snd_seq_oss_midi_open(dp, dev, dp->file_mode); case SNDCTL_SEQ_GETINCOUNT: - debug_printk(("get in count\n")); if (dp->readq == NULL || ! is_read_mode(dp->file_mode)) return 0; return put_user(dp->readq->qlen, p) ? -EFAULT : 0; case SNDCTL_SEQ_GETOUTCOUNT: - debug_printk(("get out count\n")); if (! is_write_mode(dp->file_mode) || dp->writeq == NULL) return 0; return put_user(snd_seq_oss_writeq_get_free_size(dp->writeq), p) ? -EFAULT : 0; case SNDCTL_SEQ_GETTIME: - debug_printk(("get time\n")); return put_user(snd_seq_oss_timer_cur_tick(dp->timer), p) ? -EFAULT : 0; case SNDCTL_SEQ_RESETSAMPLES: - debug_printk(("reset samples\n")); if (get_user(dev, p)) return -EFAULT; return snd_seq_oss_synth_ioctl(dp, dev, cmd, carg); case SNDCTL_SEQ_NRSYNTHS: - debug_printk(("nr synths\n")); return put_user(dp->max_synthdev, p) ? -EFAULT : 0; case SNDCTL_SEQ_NRMIDIS: - debug_printk(("nr midis\n")); return put_user(dp->max_mididev, p) ? -EFAULT : 0; case SNDCTL_SYNTH_MEMAVL: - debug_printk(("mem avail\n")); if (get_user(dev, p)) return -EFAULT; val = snd_seq_oss_synth_ioctl(dp, dev, cmd, carg); return put_user(val, p) ? -EFAULT : 0; case SNDCTL_FM_4OP_ENABLE: - debug_printk(("4op\n")); if (get_user(dev, p)) return -EFAULT; snd_seq_oss_synth_ioctl(dp, dev, cmd, carg); @@ -161,19 +149,15 @@ snd_seq_oss_ioctl(struct seq_oss_devinfo *dp, unsigned int cmd, unsigned long ca case SNDCTL_SYNTH_INFO: case SNDCTL_SYNTH_ID: - debug_printk(("synth info\n")); return snd_seq_oss_synth_info_user(dp, arg); case SNDCTL_SEQ_OUTOFBAND: - debug_printk(("out of band\n")); return snd_seq_oss_oob_user(dp, arg); case SNDCTL_MIDI_INFO: - debug_printk(("midi info\n")); return snd_seq_oss_midi_info_user(dp, arg); case SNDCTL_SEQ_THRESHOLD: - debug_printk(("threshold\n")); if (! is_write_mode(dp->file_mode)) return 0; if (get_user(val, p)) @@ -186,7 +170,6 @@ snd_seq_oss_ioctl(struct seq_oss_devinfo *dp, unsigned int cmd, unsigned long ca return 0; case SNDCTL_MIDI_PRETIME: - debug_printk(("pretime\n")); if (dp->readq == NULL || !is_read_mode(dp->file_mode)) return 0; if (get_user(val, p)) @@ -199,7 +182,6 @@ snd_seq_oss_ioctl(struct seq_oss_devinfo *dp, unsigned int cmd, unsigned long ca return put_user(val, p) ? -EFAULT : 0; default: - debug_printk(("others\n")); if (! is_write_mode(dp->file_mode)) return -EIO; return snd_seq_oss_synth_ioctl(dp, 0, cmd, carg); diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c index 0a711d2d04f..3a4569669ef 100644 --- a/sound/core/seq/oss/seq_oss_midi.c +++ b/sound/core/seq/oss/seq_oss_midi.c @@ -20,6 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <sound/asoundef.h> #include "seq_oss_midi.h" #include "seq_oss_readq.h" #include "seq_oss_timer.h" @@ -27,6 +28,7 @@ #include <sound/seq_midi_event.h> #include "../seq_lock.h" #include <linux/init.h> +#include <linux/slab.h> /* @@ -70,7 +72,7 @@ static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, * look up the existing ports * this looks a very exhausting job. */ -int __init +int snd_seq_oss_midi_lookup_ports(int client) { struct snd_seq_client_info *clinfo; @@ -151,7 +153,6 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) struct seq_oss_midi *mdev; unsigned long flags; - debug_printk(("check for MIDI client %d port %d\n", pinfo->addr.client, pinfo->addr.port)); /* the port must include generic midi */ if (! (pinfo->type & SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC)) return 0; @@ -173,7 +174,7 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) * allocate midi info record */ if ((mdev = kzalloc(sizeof(*mdev), GFP_KERNEL)) == NULL) { - snd_printk(KERN_ERR "can't malloc midi info\n"); + pr_err("ALSA: seq_oss: can't malloc midi info\n"); return -ENOMEM; } @@ -189,7 +190,7 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) /* create MIDI coder */ if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) { - snd_printk(KERN_ERR "can't malloc midi coder\n"); + pr_err("ALSA: seq_oss: can't malloc midi coder\n"); kfree(mdev); return -ENOMEM; } @@ -404,7 +405,6 @@ snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev) return 0; } - debug_printk(("closing client %d port %d mode %d\n", mdev->client, mdev->port, mdev->opened)); memset(&subs, 0, sizeof(subs)); if (mdev->opened & PERM_WRITE) { subs.sender = dp->addr; @@ -468,7 +468,6 @@ snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev) struct snd_seq_event ev; int c; - debug_printk(("resetting client %d port %d\n", mdev->client, mdev->port)); memset(&ev, 0, sizeof(ev)); ev.dest.client = mdev->client; ev.dest.port = mdev->port; @@ -476,19 +475,20 @@ snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev) ev.source.port = dp->port; if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) { ev.type = SNDRV_SEQ_EVENT_SENSING; - snd_seq_oss_dispatch(dp, &ev, 0, 0); /* active sensing */ + snd_seq_oss_dispatch(dp, &ev, 0, 0); } for (c = 0; c < 16; c++) { ev.type = SNDRV_SEQ_EVENT_CONTROLLER; ev.data.control.channel = c; - ev.data.control.param = 123; - snd_seq_oss_dispatch(dp, &ev, 0, 0); /* all notes off */ + ev.data.control.param = MIDI_CTL_ALL_NOTES_OFF; + snd_seq_oss_dispatch(dp, &ev, 0, 0); if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) { - ev.data.control.param = 121; - snd_seq_oss_dispatch(dp, &ev, 0, 0); /* reset all controllers */ + ev.data.control.param = + MIDI_CTL_RESET_CONTROLLERS; + snd_seq_oss_dispatch(dp, &ev, 0, 0); ev.type = SNDRV_SEQ_EVENT_PITCHBEND; ev.data.control.value = 0; - snd_seq_oss_dispatch(dp, &ev, 0, 0); /* bender off */ + snd_seq_oss_dispatch(dp, &ev, 0, 0); } } } diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c index f5de79f29f1..654d17a5023 100644 --- a/sound/core/seq/oss/seq_oss_readq.c +++ b/sound/core/seq/oss/seq_oss_readq.c @@ -25,6 +25,7 @@ #include <sound/seq_oss_legacy.h> #include "../seq_lock.h" #include <linux/wait.h> +#include <linux/slab.h> /* * constants @@ -47,12 +48,12 @@ snd_seq_oss_readq_new(struct seq_oss_devinfo *dp, int maxlen) struct seq_oss_readq *q; if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL) { - snd_printk(KERN_ERR "can't malloc read queue\n"); + pr_err("ALSA: seq_oss: can't malloc read queue\n"); return NULL; } if ((q->q = kcalloc(maxlen, sizeof(union evrec), GFP_KERNEL)) == NULL) { - snd_printk(KERN_ERR "can't malloc read queue buffer\n"); + pr_err("ALSA: seq_oss: can't malloc read queue buffer\n"); kfree(q); return NULL; } diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c index ab570a0a618..701feb71b70 100644 --- a/sound/core/seq/oss/seq_oss_synth.c +++ b/sound/core/seq/oss/seq_oss_synth.c @@ -24,6 +24,8 @@ #include "seq_oss_midi.h" #include "../seq_lock.h" #include <linux/init.h> +#include <linux/module.h> +#include <linux/slab.h> /* * constants @@ -104,7 +106,7 @@ snd_seq_oss_synth_register(struct snd_seq_device *dev) unsigned long flags; if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL) { - snd_printk(KERN_ERR "can't malloc synth info\n"); + pr_err("ALSA: seq_oss: can't malloc synth info\n"); return -ENOMEM; } rec->seq_device = -1; @@ -128,7 +130,7 @@ snd_seq_oss_synth_register(struct snd_seq_device *dev) if (i >= max_synth_devs) { if (max_synth_devs >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS) { spin_unlock_irqrestore(®ister_lock, flags); - snd_printk(KERN_ERR "no more synth slot\n"); + pr_err("ALSA: seq_oss: no more synth slot\n"); kfree(rec); return -ENOMEM; } @@ -136,7 +138,6 @@ snd_seq_oss_synth_register(struct snd_seq_device *dev) } rec->seq_device = i; synth_devs[i] = rec; - debug_printk(("synth %s registered %d\n", rec->name, i)); spin_unlock_irqrestore(®ister_lock, flags); dev->driver_data = rec; #ifdef SNDRV_OSS_INFO_DEV_SYNTH @@ -161,7 +162,7 @@ snd_seq_oss_synth_unregister(struct snd_seq_device *dev) } if (index >= max_synth_devs) { spin_unlock_irqrestore(®ister_lock, flags); - snd_printk(KERN_ERR "can't unregister synth\n"); + pr_err("ALSA: seq_oss: can't unregister synth\n"); return -EINVAL; } synth_devs[index] = NULL; @@ -245,11 +246,15 @@ snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp) info->nr_voices = rec->nr_voices; if (info->nr_voices > 0) { info->ch = kcalloc(info->nr_voices, sizeof(struct seq_oss_chinfo), GFP_KERNEL); - if (!info->ch) - BUG(); + if (!info->ch) { + pr_err("ALSA: seq_oss: Cannot malloc voices\n"); + rec->oper.close(&info->arg); + module_put(rec->oper.owner); + snd_use_lock_free(&rec->use_lock); + continue; + } reset_channels(info); } - debug_printk(("synth %d assigned\n", i)); info->opened++; rec->opened++; dp->synth_opened++; @@ -303,7 +308,8 @@ snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp) struct seq_oss_synth *rec; struct seq_oss_synthinfo *info; - snd_assert(dp->max_synthdev <= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS, return); + if (snd_BUG_ON(dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS)) + return; for (i = 0; i < dp->max_synthdev; i++) { info = &dp->synths[i]; if (! info->opened) @@ -318,7 +324,6 @@ snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp) if (rec == NULL) continue; if (rec->opened > 0) { - debug_printk(("synth %d closed\n", i)); rec->oper.close(&info->arg); module_put(rec->oper.owner); rec->opened = 0; @@ -397,7 +402,8 @@ snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev) struct seq_oss_synth *rec; struct seq_oss_synthinfo *info; - snd_assert(dev >= 0 && dev < dp->max_synthdev, return); + if (snd_BUG_ON(dev < 0 || dev >= dp->max_synthdev)) + return; info = &dp->synths[dev]; if (! info->opened) return; @@ -599,6 +605,9 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in { struct seq_oss_synth *rec; + if (dev < 0 || dev >= dp->max_synthdev) + return -ENXIO; + if (dp->synths[dev].is_midi) { struct midi_info minf; snd_seq_oss_midi_make_info(dp, dp->synths[dev].midi_mapped, &minf); diff --git a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c index c440fdacec9..4f24ea9fad9 100644 --- a/sound/core/seq/oss/seq_oss_timer.c +++ b/sound/core/seq/oss/seq_oss_timer.c @@ -23,6 +23,7 @@ #include "seq_oss_timer.h" #include "seq_oss_event.h" #include <sound/seq_oss_legacy.h> +#include <linux/slab.h> /* */ @@ -232,7 +233,6 @@ snd_seq_oss_timer_ioctl(struct seq_oss_timer *timer, unsigned int cmd, int __use int value; if (cmd == SNDCTL_SEQ_CTRLRATE) { - debug_printk(("ctrl rate\n")); /* if *arg == 0, just return the current rate */ if (get_user(value, arg)) return -EFAULT; @@ -247,21 +247,16 @@ snd_seq_oss_timer_ioctl(struct seq_oss_timer *timer, unsigned int cmd, int __use switch (cmd) { case SNDCTL_TMR_START: - debug_printk(("timer start\n")); return snd_seq_oss_timer_start(timer); case SNDCTL_TMR_STOP: - debug_printk(("timer stop\n")); return snd_seq_oss_timer_stop(timer); case SNDCTL_TMR_CONTINUE: - debug_printk(("timer continue\n")); return snd_seq_oss_timer_continue(timer); case SNDCTL_TMR_TEMPO: - debug_printk(("timer tempo\n")); if (get_user(value, arg)) return -EFAULT; return snd_seq_oss_timer_tempo(timer, value); case SNDCTL_TMR_TIMEBASE: - debug_printk(("timer timebase\n")); if (get_user(value, arg)) return -EFAULT; if (value < MIN_OSS_TIMEBASE) @@ -275,7 +270,6 @@ snd_seq_oss_timer_ioctl(struct seq_oss_timer *timer, unsigned int cmd, int __use case SNDCTL_TMR_METRONOME: case SNDCTL_TMR_SELECT: case SNDCTL_TMR_SOURCE: - debug_printk(("timer XXX\n")); /* not supported */ return 0; } diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c index 5c8495601a3..d50338bbc21 100644 --- a/sound/core/seq/oss/seq_oss_writeq.c +++ b/sound/core/seq/oss/seq_oss_writeq.c @@ -27,6 +27,7 @@ #include "../seq_lock.h" #include "../seq_clientmgr.h" #include <linux/wait.h> +#include <linux/slab.h> /* @@ -63,8 +64,10 @@ snd_seq_oss_writeq_new(struct seq_oss_devinfo *dp, int maxlen) void snd_seq_oss_writeq_delete(struct seq_oss_writeq *q) { - snd_seq_oss_writeq_clear(q); /* to be sure */ - kfree(q); + if (q) { + snd_seq_oss_writeq_clear(q); /* to be sure */ + kfree(q); + } } diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c index 20f954bc7aa..71211056108 100644 --- a/sound/core/seq/seq.c +++ b/sound/core/seq/seq.c @@ -19,9 +19,9 @@ * */ -#include <sound/driver.h> #include <linux/init.h> -#include <linux/moduleparam.h> +#include <linux/module.h> +#include <linux/device.h> #include <sound/core.h> #include <sound/initval.h> @@ -33,6 +33,7 @@ #include "seq_timer.h" #include "seq_system.h" #include "seq_info.h" +#include <sound/minors.h> #include <sound/seq_device.h> #if defined(CONFIG_SND_SEQ_DUMMY_MODULE) @@ -44,7 +45,9 @@ int seq_default_timer_class = SNDRV_TIMER_CLASS_GLOBAL; int seq_default_timer_sclass = SNDRV_TIMER_SCLASS_NONE; int seq_default_timer_card = -1; int seq_default_timer_device = -#ifdef CONFIG_SND_SEQ_RTCTIMER_DEFAULT +#ifdef CONFIG_SND_SEQ_HRTIMER_DEFAULT + SNDRV_TIMER_GLOBAL_HRTIMER +#elif defined(CONFIG_SND_SEQ_RTCTIMER_DEFAULT) SNDRV_TIMER_GLOBAL_RTC #else SNDRV_TIMER_GLOBAL_SYSTEM @@ -53,7 +56,7 @@ int seq_default_timer_device = int seq_default_timer_subdevice = 0; int seq_default_timer_resolution = 0; /* Hz */ -MODULE_AUTHOR("Frank van de Pol <fvdpol@coil.demon.nl>, Jaroslav Kysela <perex@suse.cz>"); +MODULE_AUTHOR("Frank van de Pol <fvdpol@coil.demon.nl>, Jaroslav Kysela <perex@perex.cz>"); MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer."); MODULE_LICENSE("GPL"); @@ -72,6 +75,9 @@ MODULE_PARM_DESC(seq_default_timer_subdevice, "The default timer subdevice numbe module_param(seq_default_timer_resolution, int, 0644); MODULE_PARM_DESC(seq_default_timer_resolution, "The default timer resolution in Hz."); +MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_SEQUENCER); +MODULE_ALIAS("devname:snd/seq"); + /* * INIT PART */ @@ -129,25 +135,3 @@ static void __exit alsa_seq_exit(void) module_init(alsa_seq_init) module_exit(alsa_seq_exit) - - /* seq_clientmgr.c */ -EXPORT_SYMBOL(snd_seq_create_kernel_client); -EXPORT_SYMBOL(snd_seq_delete_kernel_client); -EXPORT_SYMBOL(snd_seq_kernel_client_enqueue); -EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking); -EXPORT_SYMBOL(snd_seq_kernel_client_dispatch); -EXPORT_SYMBOL(snd_seq_kernel_client_ctl); -EXPORT_SYMBOL(snd_seq_kernel_client_write_poll); -EXPORT_SYMBOL(snd_seq_set_queue_tempo); - /* seq_memory.c */ -EXPORT_SYMBOL(snd_seq_expand_var_event); -EXPORT_SYMBOL(snd_seq_dump_var_event); - /* seq_ports.c */ -EXPORT_SYMBOL(snd_seq_event_port_attach); -EXPORT_SYMBOL(snd_seq_event_port_detach); - /* seq_lock.c */ -#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG) -/*EXPORT_SYMBOL(snd_seq_sleep_in_lock);*/ -/*EXPORT_SYMBOL(snd_seq_sleep_timeout_in_lock);*/ -EXPORT_SYMBOL(snd_use_lock_sync_helper); -#endif diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index fd2032eae21..225c73152ee 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -1,7 +1,7 @@ /* * ALSA sequencer Client Manager * Copyright (c) 1998-2001 by Frank van de Pol <fvdpol@coil.demon.nl> - * Jaroslav Kysela <perex@suse.cz> + * Jaroslav Kysela <perex@perex.cz> * Takashi Iwai <tiwai@suse.de> * * @@ -21,9 +21,8 @@ * */ -#include <sound/driver.h> #include <linux/init.h> -#include <linux/smp_lock.h> +#include <linux/export.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/minors.h> @@ -67,7 +66,7 @@ #define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT) static DEFINE_SPINLOCK(clients_lock); -static DECLARE_MUTEX(register_mutex); +static DEFINE_MUTEX(register_mutex); /* * client table @@ -124,22 +123,20 @@ static inline int snd_seq_write_pool_allocated(struct snd_seq_client *client) static struct snd_seq_client *clientptr(int clientid) { if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) { - snd_printd("Seq: oops. Trying to get pointer to client %d\n", + pr_debug("ALSA: seq: oops. Trying to get pointer to client %d\n", clientid); return NULL; } return clienttab[clientid]; } -extern int seq_client_load[]; - struct snd_seq_client *snd_seq_client_use_ptr(int clientid) { unsigned long flags; struct snd_seq_client *client; if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) { - snd_printd("Seq: oops. Trying to get pointer to client %d\n", + pr_debug("ALSA: seq: oops. Trying to get pointer to client %d\n", clientid); return NULL; } @@ -152,14 +149,14 @@ struct snd_seq_client *snd_seq_client_use_ptr(int clientid) return NULL; } spin_unlock_irqrestore(&clients_lock, flags); -#ifdef CONFIG_KMOD - if (!in_interrupt() && current->fs->root) { +#ifdef CONFIG_MODULES + if (!in_interrupt()) { static char client_requested[SNDRV_SEQ_GLOBAL_CLIENTS]; static char card_requested[SNDRV_CARDS]; if (clientid < SNDRV_SEQ_GLOBAL_CLIENTS) { int idx; - if (! client_requested[clientid] && current->fs->root) { + if (!client_requested[clientid]) { client_requested[clientid] = 1; for (idx = 0; idx < 15; idx++) { if (seq_client_load[idx] < 0) @@ -237,7 +234,7 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize) client->type = NO_CLIENT; snd_use_lock_init(&client->use_lock); rwlock_init(&client->ports_lock); - init_MUTEX(&client->ports_mutex); + mutex_init(&client->ports_mutex); INIT_LIST_HEAD(&client->ports_list_head); /* find free slot in the client table */ @@ -270,7 +267,8 @@ static int seq_free_client1(struct snd_seq_client *client) { unsigned long flags; - snd_assert(client != NULL, return -EINVAL); + if (!client) + return 0; snd_seq_delete_all_ports(client); snd_seq_queue_client_leave(client->number); spin_lock_irqsave(&clients_lock, flags); @@ -290,11 +288,11 @@ static int seq_free_client1(struct snd_seq_client *client) static void seq_free_client(struct snd_seq_client * client) { - down(®ister_mutex); + mutex_lock(®ister_mutex); switch (client->type) { case NO_CLIENT: - snd_printk(KERN_WARNING "Seq: Trying to free unused client %d\n", - client->number); + pr_warn("ALSA: seq: Trying to free unused client %d\n", + client->number); break; case USER_CLIENT: case KERNEL_CLIENT: @@ -303,10 +301,10 @@ static void seq_free_client(struct snd_seq_client * client) break; default: - snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n", + pr_err("ALSA: seq: Trying to free client %d with undefined type = %d\n", client->number, client->type); } - up(®ister_mutex); + mutex_unlock(®ister_mutex); snd_seq_system_client_ev_client_exit(client->number); } @@ -321,12 +319,17 @@ static int snd_seq_open(struct inode *inode, struct file *file) int c, mode; /* client id */ struct snd_seq_client *client; struct snd_seq_user_client *user; + int err; - if (down_interruptible(®ister_mutex)) + err = nonseekable_open(inode, file); + if (err < 0) + return err; + + if (mutex_lock_interruptible(®ister_mutex)) return -ERESTARTSYS; client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS); if (client == NULL) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -ENOMEM; /* failure code */ } @@ -346,14 +349,14 @@ static int snd_seq_open(struct inode *inode, struct file *file) if (user->fifo == NULL) { seq_free_client1(client); kfree(client); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -ENOMEM; } } usage_alloc(&client_usage, 1); client->type = USER_CLIENT; - up(®ister_mutex); + mutex_unlock(®ister_mutex); c = client->number; file->private_data = client; @@ -407,7 +410,8 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count, return -EFAULT; /* check client structures are in place */ - snd_assert(client != NULL, return -ENXIO); + if (snd_BUG_ON(!client)) + return -ENXIO; if (!client->accept_input || (fifo = client->data.user.fifo) == NULL) return -ENXIO; @@ -656,10 +660,9 @@ static int deliver_to_subscribers(struct snd_seq_client *client, int atomic, int hop) { struct snd_seq_subscribers *subs; - int err = 0, num_ev = 0; + int err, result = 0, num_ev = 0; struct snd_seq_event event_saved; struct snd_seq_client_port *src_port; - struct list_head *p; struct snd_seq_port_subs_info *grp; src_port = snd_seq_port_use_ptr(client, event->source.port); @@ -674,8 +677,7 @@ static int deliver_to_subscribers(struct snd_seq_client *client, read_lock(&grp->list_lock); else down_read(&grp->list_mutex); - list_for_each(p, &grp->list_head) { - subs = list_entry(p, struct snd_seq_subscribers, src_list); + list_for_each_entry(subs, &grp->list_head, src_list) { event->dest = subs->info.dest; if (subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) /* convert time according to flag with subscription */ @@ -683,8 +685,12 @@ static int deliver_to_subscribers(struct snd_seq_client *client, subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL); err = snd_seq_deliver_single_event(client, event, 0, atomic, hop); - if (err < 0) - break; + if (err < 0) { + /* save first error that occurs and continue */ + if (!result) + result = err; + continue; + } num_ev++; /* restore original event record */ *event = event_saved; @@ -695,7 +701,7 @@ static int deliver_to_subscribers(struct snd_seq_client *client, up_read(&grp->list_mutex); *event = event_saved; /* restore */ snd_seq_port_unlock(src_port); - return (err < 0) ? err : num_ev; + return (result < 0) ? result : num_ev; } @@ -707,30 +713,33 @@ static int port_broadcast_event(struct snd_seq_client *client, struct snd_seq_event *event, int atomic, int hop) { - int num_ev = 0, err = 0; + int num_ev = 0, err, result = 0; struct snd_seq_client *dest_client; - struct list_head *p; + struct snd_seq_client_port *port; dest_client = get_event_dest_client(event, SNDRV_SEQ_FILTER_BROADCAST); if (dest_client == NULL) return 0; /* no matching destination */ read_lock(&dest_client->ports_lock); - list_for_each(p, &dest_client->ports_list_head) { - struct snd_seq_client_port *port = list_entry(p, struct snd_seq_client_port, list); + list_for_each_entry(port, &dest_client->ports_list_head, list) { event->dest.port = port->addr.port; /* pass NULL as source client to avoid error bounce */ err = snd_seq_deliver_single_event(NULL, event, SNDRV_SEQ_FILTER_BROADCAST, atomic, hop); - if (err < 0) - break; + if (err < 0) { + /* save first error that occurs and continue */ + if (!result) + result = err; + continue; + } num_ev++; } read_unlock(&dest_client->ports_lock); snd_seq_client_unlock(dest_client); event->dest.port = SNDRV_SEQ_ADDRESS_BROADCAST; /* restore */ - return (err < 0) ? err : num_ev; + return (result < 0) ? result : num_ev; } /* @@ -740,7 +749,7 @@ static int port_broadcast_event(struct snd_seq_client *client, static int broadcast_event(struct snd_seq_client *client, struct snd_seq_event *event, int atomic, int hop) { - int err = 0, num_ev = 0; + int err, result = 0, num_ev = 0; int dest; struct snd_seq_addr addr; @@ -759,12 +768,16 @@ static int broadcast_event(struct snd_seq_client *client, err = snd_seq_deliver_single_event(NULL, event, SNDRV_SEQ_FILTER_BROADCAST, atomic, hop); - if (err < 0) - break; + if (err < 0) { + /* save first error that occurs and continue */ + if (!result) + result = err; + continue; + } num_ev += err; } event->dest = addr; /* restore */ - return (err < 0) ? err : num_ev; + return (result < 0) ? result : num_ev; } @@ -772,7 +785,7 @@ static int broadcast_event(struct snd_seq_client *client, static int multicast_event(struct snd_seq_client *client, struct snd_seq_event *event, int atomic, int hop) { - snd_printd("seq: multicast not supported yet.\n"); + pr_debug("ALSA: seq: multicast not supported yet.\n"); return 0; /* ignored */ } #endif /* SUPPORT_BROADCAST */ @@ -793,7 +806,7 @@ static int snd_seq_deliver_event(struct snd_seq_client *client, struct snd_seq_e hop++; if (hop >= SNDRV_SEQ_MAX_HOPS) { - snd_printd("too long delivery path (%d:%d->%d:%d)\n", + pr_debug("ALSA: seq: too long delivery path (%d:%d->%d:%d)\n", event->source.client, event->source.port, event->dest.client, event->dest.port); return -EMLINK; @@ -832,7 +845,8 @@ int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop) struct snd_seq_client *client; int result; - snd_assert(cell != NULL, return -EINVAL); + if (snd_BUG_ON(!cell)) + return -EINVAL; client = snd_seq_client_use_ptr(cell->event.source.client); if (client == NULL) { @@ -970,8 +984,7 @@ static int check_event_type_and_length(struct snd_seq_event *ev) return -EINVAL; break; case SNDRV_SEQ_EVENT_LENGTH_VARUSR: - if (! snd_seq_ev_is_instr_type(ev) || - ! snd_seq_ev_is_direct(ev)) + if (! snd_seq_ev_is_direct(ev)) return -EINVAL; break; } @@ -1002,7 +1015,8 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf, return -ENXIO; /* check client structures are in place */ - snd_assert(client != NULL, return -ENXIO); + if (snd_BUG_ON(!client)) + return -ENXIO; if (!client->accept_output || client->pool == NULL) return -ENXIO; @@ -1051,7 +1065,7 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf, } else { #ifdef CONFIG_COMPAT if (client->convert32 && snd_seq_ev_is_varusr(&event)) { - void *ptr = compat_ptr(event.data.raw32.d[1]); + void *ptr = (void __force *)compat_ptr(event.data.raw32.d[1]); event.data.ext.ptr = ptr; } #endif @@ -1084,7 +1098,8 @@ static unsigned int snd_seq_poll(struct file *file, poll_table * wait) unsigned int mask = 0; /* check client structures are in place */ - snd_assert(client != NULL, return -ENXIO); + if (snd_BUG_ON(!client)) + return -ENXIO; if ((snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_INPUT) && client->data.user.fifo) { @@ -1714,6 +1729,8 @@ int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo) return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo); } +EXPORT_SYMBOL(snd_seq_set_queue_tempo); + static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client, void __user *arg) { @@ -1743,7 +1760,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client, if (queue == NULL) return -EINVAL; - if (down_interruptible(&queue->timer_mutex)) { + if (mutex_lock_interruptible(&queue->timer_mutex)) { queuefree(queue); return -ERESTARTSYS; } @@ -1756,7 +1773,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client, timer.u.alsa.id = tmr->alsa_id; timer.u.alsa.resolution = tmr->preferred_resolution; } - up(&queue->timer_mutex); + mutex_unlock(&queue->timer_mutex); queuefree(queue); if (copy_to_user(arg, &timer, sizeof(timer))) @@ -1785,7 +1802,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client, q = queueptr(timer.queue); if (q == NULL) return -ENXIO; - if (down_interruptible(&q->timer_mutex)) { + if (mutex_lock_interruptible(&q->timer_mutex)) { queuefree(q); return -ERESTARTSYS; } @@ -1797,7 +1814,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client, tmr->preferred_resolution = timer.u.alsa.resolution; } result = snd_seq_queue_timer_open(timer.queue); - up(&q->timer_mutex); + mutex_unlock(&q->timer_mutex); queuefree(q); } else { return -EPERM; @@ -1866,8 +1883,7 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client, info.output_pool = cptr->pool->size; info.output_room = cptr->pool->room; info.output_free = info.output_pool; - if (cptr->pool) - info.output_free = snd_seq_unused_cells(cptr->pool); + info.output_free = snd_seq_unused_cells(cptr->pool); if (cptr->type == USER_CLIENT) { info.input_pool = cptr->data.user.fifo_pool_size; info.input_free = info.input_pool; @@ -2192,7 +2208,7 @@ static int snd_seq_do_ioctl(struct snd_seq_client *client, unsigned int cmd, if (p->cmd == cmd) return p->func(client, arg); } - snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%2x)\n", + pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n", cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); return -ENOTTY; } @@ -2202,7 +2218,8 @@ static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long arg { struct snd_seq_client *client = file->private_data; - snd_assert(client != NULL, return -ENXIO); + if (snd_BUG_ON(!client)) + return -ENXIO; return snd_seq_do_ioctl(client, cmd, (void __user *) arg); } @@ -2223,14 +2240,15 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, struct snd_seq_client *client; va_list args; - snd_assert(! in_interrupt(), return -EBUSY); + if (snd_BUG_ON(in_interrupt())) + return -EBUSY; if (card && client_index >= SNDRV_SEQ_CLIENTS_PER_CARD) return -EINVAL; if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS) return -EINVAL; - if (down_interruptible(®ister_mutex)) + if (mutex_lock_interruptible(®ister_mutex)) return -ERESTARTSYS; if (card) { @@ -2243,7 +2261,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, /* empty write queue as default */ client = seq_create_client1(client_index, 0); if (client == NULL) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -EBUSY; /* failure code */ } usage_alloc(&client_usage, 1); @@ -2256,7 +2274,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, va_end(args); client->type = KERNEL_CLIENT; - up(®ister_mutex); + mutex_unlock(®ister_mutex); /* make others aware this new client */ snd_seq_system_client_ev_client_start(client->number); @@ -2265,12 +2283,15 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, return client->number; } +EXPORT_SYMBOL(snd_seq_create_kernel_client); + /* exported to kernel modules */ int snd_seq_delete_kernel_client(int client) { struct snd_seq_client *ptr; - snd_assert(! in_interrupt(), return -EBUSY); + if (snd_BUG_ON(in_interrupt())) + return -EBUSY; ptr = clientptr(client); if (ptr == NULL) @@ -2281,6 +2302,7 @@ int snd_seq_delete_kernel_client(int client) return 0; } +EXPORT_SYMBOL(snd_seq_delete_kernel_client); /* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue * and snd_seq_kernel_client_enqueue_blocking @@ -2292,7 +2314,8 @@ static int kernel_client_enqueue(int client, struct snd_seq_event *ev, struct snd_seq_client *cptr; int result; - snd_assert(ev != NULL, return -EINVAL); + if (snd_BUG_ON(!ev)) + return -EINVAL; if (ev->type == SNDRV_SEQ_EVENT_NONE) return 0; /* ignore this */ @@ -2329,6 +2352,8 @@ int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event * ev, return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop); } +EXPORT_SYMBOL(snd_seq_kernel_client_enqueue); + /* * exported, called by kernel clients to enqueue events (with blocking) * @@ -2341,6 +2366,7 @@ int snd_seq_kernel_client_enqueue_blocking(int client, struct snd_seq_event * ev return kernel_client_enqueue(client, ev, file, 1, atomic, hop); } +EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking); /* * exported, called by kernel clients to dispatch events directly to other @@ -2355,7 +2381,8 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev, struct snd_seq_client *cptr; int result; - snd_assert(ev != NULL, return -EINVAL); + if (snd_BUG_ON(!ev)) + return -EINVAL; /* fill in client number */ ev->queue = SNDRV_SEQ_QUEUE_DIRECT; @@ -2377,6 +2404,7 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev, return result; } +EXPORT_SYMBOL(snd_seq_kernel_client_dispatch); /* * exported, called by kernel clients to perform same functions as with @@ -2392,11 +2420,12 @@ int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg) if (client == NULL) return -ENXIO; fs = snd_enter_user(); - result = snd_seq_do_ioctl(client, cmd, (void __user *)arg); + result = snd_seq_do_ioctl(client, cmd, (void __force __user *)arg); snd_leave_user(fs); return result; } +EXPORT_SYMBOL(snd_seq_kernel_client_ctl); /* exported (for OSS emulator) */ int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait) @@ -2414,6 +2443,8 @@ int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table return 0; } +EXPORT_SYMBOL(snd_seq_kernel_client_write_poll); + /*---------------------------------------------------------------------------*/ #ifdef CONFIG_PROC_FS @@ -2462,11 +2493,10 @@ static void snd_seq_info_dump_subscribers(struct snd_info_buffer *buffer, static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer, struct snd_seq_client *client) { - struct list_head *l; + struct snd_seq_client_port *p; - down(&client->ports_mutex); - list_for_each(l, &client->ports_list_head) { - struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); + mutex_lock(&client->ports_mutex); + list_for_each_entry(p, &client->ports_list_head, list) { snd_iprintf(buffer, " Port %3d : \"%s\" (%c%c%c%c)\n", p->addr.port, p->name, FLAG_PERM_RD(p->capability), @@ -2476,13 +2506,10 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer, snd_seq_info_dump_subscribers(buffer, &p->c_src, 1, " Connecting To: "); snd_seq_info_dump_subscribers(buffer, &p->c_dest, 0, " Connected From: "); } - up(&client->ports_mutex); + mutex_unlock(&client->ports_mutex); } -void snd_seq_info_pool(struct snd_info_buffer *buffer, - struct snd_seq_pool *pool, char *space); - /* exported to seq_info.c */ void snd_seq_info_clients_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) @@ -2531,13 +2558,14 @@ void snd_seq_info_clients_read(struct snd_info_entry *entry, * REGISTRATION PART */ -static struct file_operations snd_seq_f_ops = +static const struct file_operations snd_seq_f_ops = { .owner = THIS_MODULE, .read = snd_seq_read, .write = snd_seq_write, .open = snd_seq_open, .release = snd_seq_release, + .llseek = no_llseek, .poll = snd_seq_poll, .unlocked_ioctl = snd_seq_ioctl, .compat_ioctl = snd_seq_ioctl_compat, @@ -2550,16 +2578,16 @@ int __init snd_sequencer_device_init(void) { int err; - if (down_interruptible(®ister_mutex)) + if (mutex_lock_interruptible(®ister_mutex)) return -ERESTARTSYS; if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0, &snd_seq_f_ops, NULL, "seq")) < 0) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return err; } - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } diff --git a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h index 450091ca153..20f0a725ec7 100644 --- a/sound/core/seq/seq_clientmgr.h +++ b/sound/core/seq/seq_clientmgr.h @@ -58,7 +58,7 @@ struct snd_seq_client { int num_ports; /* number of ports */ struct list_head ports_list_head; rwlock_t ports_lock; - struct semaphore ports_mutex; + struct mutex ports_mutex; int convert32; /* convert 32->64bit */ /* output pool */ @@ -98,4 +98,6 @@ int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table int snd_seq_client_notify_subscription(int client, int port, struct snd_seq_port_subscribe *info, int evtype); +extern int seq_client_load[15]; + #endif diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c index 9628c06e4ea..81f7c109dc4 100644 --- a/sound/core/seq/seq_compat.c +++ b/sound/core/seq/seq_compat.c @@ -21,6 +21,7 @@ /* This file included from seq.c */ #include <linux/compat.h> +#include <linux/slab.h> struct snd_seq_port_info32 { struct snd_seq_addr addr; /* client/port numbers */ @@ -48,12 +49,11 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned struct snd_seq_port_info *data; mm_segment_t fs; - data = kmalloc(sizeof(*data), GFP_KERNEL); - if (! data) - return -ENOMEM; + data = memdup_user(data32, sizeof(*data32)); + if (IS_ERR(data)) + return PTR_ERR(data); - if (copy_from_user(data, data32, sizeof(*data32)) || - get_user(data->flags, &data32->flags) || + if (get_user(data->flags, &data32->flags) || get_user(data->time_queue, &data32->time_queue)) goto error; data->kernel = NULL; @@ -92,7 +92,8 @@ static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned l struct snd_seq_client *client = file->private_data; void __user *argp = compat_ptr(arg); - snd_assert(client != NULL, return -ENXIO); + if (snd_BUG_ON(!client)) + return -ENXIO; switch (cmd) { case SNDRV_SEQ_IOCTL_PVERSION: diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index 9ece443fba5..91a786a783e 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -36,8 +36,8 @@ * */ -#include <sound/driver.h> #include <linux/init.h> +#include <linux/module.h> #include <sound/core.h> #include <sound/info.h> #include <sound/seq_device.h> @@ -45,6 +45,7 @@ #include <sound/initval.h> #include <linux/kmod.h> #include <linux/slab.h> +#include <linux/mutex.h> MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); MODULE_DESCRIPTION("ALSA sequencer device management"); @@ -65,11 +66,11 @@ struct ops_list { /* operators */ struct snd_seq_dev_ops ops; - /* registred devices */ + /* registered devices */ struct list_head dev_list; /* list of devices */ int num_devices; /* number of associated devices */ int num_init_devices; /* number of initialized devices */ - struct semaphore reg_mutex; + struct mutex reg_mutex; struct list_head list; /* next driver */ }; @@ -77,9 +78,9 @@ struct ops_list { static LIST_HEAD(opslist); static int num_ops; -static DECLARE_MUTEX(ops_mutex); +static DEFINE_MUTEX(ops_mutex); #ifdef CONFIG_PROC_FS -static struct snd_info_entry *info_entry = NULL; +static struct snd_info_entry *info_entry; #endif /* @@ -89,7 +90,6 @@ static int snd_seq_device_free(struct snd_seq_device *dev); static int snd_seq_device_dev_free(struct snd_device *device); static int snd_seq_device_dev_register(struct snd_device *device); static int snd_seq_device_dev_disconnect(struct snd_device *device); -static int snd_seq_device_dev_unregister(struct snd_device *device); static int init_device(struct snd_seq_device *dev, struct ops_list *ops); static int free_device(struct snd_seq_device *dev, struct ops_list *ops); @@ -106,11 +106,10 @@ static void remove_drivers(void); static void snd_seq_device_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { - struct list_head *head; + struct ops_list *ops; - down(&ops_mutex); - list_for_each(head, &opslist) { - struct ops_list *ops = list_entry(head, struct ops_list, list); + mutex_lock(&ops_mutex); + list_for_each_entry(ops, &opslist, list) { snd_iprintf(buffer, "snd-%s%s%s%s,%d\n", ops->id, ops->driver & DRIVER_LOADED ? ",loaded" : (ops->driver == DRIVER_EMPTY ? ",empty" : ""), @@ -118,7 +117,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry, ops->driver & DRIVER_LOCKED ? ",locked" : "", ops->num_devices); } - up(&ops_mutex); + mutex_unlock(&ops_mutex); } #endif @@ -126,7 +125,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry, * load all registered drivers (called from seq_clientmgr.c) */ -#ifdef CONFIG_KMOD +#ifdef CONFIG_MODULES /* avoid auto-loading during module_init() */ static int snd_seq_in_init; void snd_seq_autoload_lock(void) @@ -142,8 +141,8 @@ void snd_seq_autoload_unlock(void) void snd_seq_device_load_drivers(void) { -#ifdef CONFIG_KMOD - struct list_head *head; +#ifdef CONFIG_MODULES + struct ops_list *ops; /* Calling request_module during module_init() * may cause blocking. @@ -151,29 +150,25 @@ void snd_seq_device_load_drivers(void) if (snd_seq_in_init) return; - if (! current->fs->root) - return; - - down(&ops_mutex); - list_for_each(head, &opslist) { - struct ops_list *ops = list_entry(head, struct ops_list, list); + mutex_lock(&ops_mutex); + list_for_each_entry(ops, &opslist, list) { if (! (ops->driver & DRIVER_LOADED) && ! (ops->driver & DRIVER_REQUESTED)) { ops->used++; - up(&ops_mutex); + mutex_unlock(&ops_mutex); ops->driver |= DRIVER_REQUESTED; request_module("snd-%s", ops->id); - down(&ops_mutex); + mutex_lock(&ops_mutex); ops->used--; } } - up(&ops_mutex); + mutex_unlock(&ops_mutex); #endif } /* * register a sequencer device - * card = card info (NULL allowed) + * card = card info * device = device number (if any) * id = id of driver * result = return pointer (NULL allowed if unnecessary) @@ -188,13 +183,13 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, .dev_free = snd_seq_device_dev_free, .dev_register = snd_seq_device_dev_register, .dev_disconnect = snd_seq_device_dev_disconnect, - .dev_unregister = snd_seq_device_dev_unregister }; if (result) *result = NULL; - snd_assert(id != NULL, return -EINVAL); + if (snd_BUG_ON(!id)) + return -EINVAL; ops = find_driver(id, 1); if (ops == NULL) @@ -214,10 +209,10 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, dev->status = SNDRV_SEQ_DEVICE_FREE; /* add this device to the list */ - down(&ops->reg_mutex); + mutex_lock(&ops->reg_mutex); list_add_tail(&dev->list, &ops->dev_list); ops->num_devices++; - up(&ops->reg_mutex); + mutex_unlock(&ops->reg_mutex); unlock_driver(ops); @@ -239,17 +234,18 @@ static int snd_seq_device_free(struct snd_seq_device *dev) { struct ops_list *ops; - snd_assert(dev != NULL, return -EINVAL); + if (snd_BUG_ON(!dev)) + return -EINVAL; ops = find_driver(dev->id, 0); if (ops == NULL) return -ENXIO; /* remove the device from the list */ - down(&ops->reg_mutex); + mutex_lock(&ops->reg_mutex); list_del(&dev->list); ops->num_devices--; - up(&ops->reg_mutex); + mutex_unlock(&ops->reg_mutex); free_device(dev, ops); if (dev->private_free) @@ -308,15 +304,6 @@ static int snd_seq_device_dev_disconnect(struct snd_device *device) } /* - * unregister the existing device - */ -static int snd_seq_device_dev_unregister(struct snd_device *device) -{ - struct snd_seq_device *dev = device->device_data; - return snd_seq_device_free(dev); -} - -/* * register device driver * id = driver id * entry = driver operators - duplicated to each instance @@ -324,8 +311,8 @@ static int snd_seq_device_dev_unregister(struct snd_device *device) int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, int argsize) { - struct list_head *head; struct ops_list *ops; + struct snd_seq_device *dev; if (id == NULL || entry == NULL || entry->init_device == NULL || entry->free_device == NULL) @@ -338,24 +325,23 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, return -ENOMEM; } if (ops->driver & DRIVER_LOADED) { - snd_printk(KERN_WARNING "driver_register: driver '%s' already exists\n", id); + pr_warn("ALSA: seq: driver_register: driver '%s' already exists\n", id); unlock_driver(ops); snd_seq_autoload_unlock(); return -EBUSY; } - down(&ops->reg_mutex); + mutex_lock(&ops->reg_mutex); /* copy driver operators */ ops->ops = *entry; ops->driver |= DRIVER_LOADED; ops->argsize = argsize; /* initialize existing devices if necessary */ - list_for_each(head, &ops->dev_list) { - struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list); + list_for_each_entry(dev, &ops->dev_list, list) { init_device(dev, ops); } - up(&ops->reg_mutex); + mutex_unlock(&ops->reg_mutex); unlock_driver(ops); snd_seq_autoload_unlock(); @@ -371,24 +357,29 @@ static struct ops_list * create_driver(char *id) { struct ops_list *ops; - ops = kmalloc(sizeof(*ops), GFP_KERNEL); + ops = kzalloc(sizeof(*ops), GFP_KERNEL); if (ops == NULL) return ops; - memset(ops, 0, sizeof(*ops)); /* set up driver entry */ strlcpy(ops->id, id, sizeof(ops->id)); - init_MUTEX(&ops->reg_mutex); + mutex_init(&ops->reg_mutex); + /* + * The ->reg_mutex locking rules are per-driver, so we create + * separate per-driver lock classes: + */ + lockdep_set_class(&ops->reg_mutex, (struct lock_class_key *)id); + ops->driver = DRIVER_EMPTY; INIT_LIST_HEAD(&ops->dev_list); /* lock this instance */ ops->used = 1; /* register driver entry */ - down(&ops_mutex); + mutex_lock(&ops_mutex); list_add_tail(&ops->list, &opslist); num_ops++; - up(&ops_mutex); + mutex_unlock(&ops_mutex); return ops; } @@ -399,33 +390,32 @@ static struct ops_list * create_driver(char *id) */ int snd_seq_device_unregister_driver(char *id) { - struct list_head *head; struct ops_list *ops; + struct snd_seq_device *dev; ops = find_driver(id, 0); if (ops == NULL) return -ENXIO; if (! (ops->driver & DRIVER_LOADED) || (ops->driver & DRIVER_LOCKED)) { - snd_printk(KERN_ERR "driver_unregister: cannot unload driver '%s': status=%x\n", + pr_err("ALSA: seq: driver_unregister: cannot unload driver '%s': status=%x\n", id, ops->driver); unlock_driver(ops); return -EBUSY; } /* close and release all devices associated with this driver */ - down(&ops->reg_mutex); + mutex_lock(&ops->reg_mutex); ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */ - list_for_each(head, &ops->dev_list) { - struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list); + list_for_each_entry(dev, &ops->dev_list, list) { free_device(dev, ops); } ops->driver = 0; if (ops->num_init_devices > 0) - snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n", + pr_err("ALSA: seq: free_driver: init_devices > 0!! (%d)\n", ops->num_init_devices); - up(&ops->reg_mutex); + mutex_unlock(&ops->reg_mutex); unlock_driver(ops); @@ -443,7 +433,7 @@ static void remove_drivers(void) { struct list_head *head; - down(&ops_mutex); + mutex_lock(&ops_mutex); head = opslist.next; while (head != &opslist) { struct ops_list *ops = list_entry(head, struct ops_list, list); @@ -456,7 +446,7 @@ static void remove_drivers(void) } else head = head->next; } - up(&ops_mutex); + mutex_unlock(&ops_mutex); } /* @@ -469,7 +459,7 @@ static int init_device(struct snd_seq_device *dev, struct ops_list *ops) if (dev->status != SNDRV_SEQ_DEVICE_FREE) return 0; /* already initialized */ if (ops->argsize != dev->argsize) { - snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n", + pr_err("ALSA: seq: incompatible device '%s' for plug-in '%s' (%d %d)\n", dev->name, ops->id, ops->argsize, dev->argsize); return -EINVAL; } @@ -477,7 +467,7 @@ static int init_device(struct snd_seq_device *dev, struct ops_list *ops) dev->status = SNDRV_SEQ_DEVICE_REGISTERED; ops->num_init_devices++; } else { - snd_printk(KERN_ERR "init_device failed: %s: %s\n", + pr_err("ALSA: seq: init_device failed: %s: %s\n", dev->name, dev->id); } @@ -496,7 +486,7 @@ static int free_device(struct snd_seq_device *dev, struct ops_list *ops) if (dev->status != SNDRV_SEQ_DEVICE_REGISTERED) return 0; /* not registered */ if (ops->argsize != dev->argsize) { - snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n", + pr_err("ALSA: seq: incompatible device '%s' for plug-in '%s' (%d %d)\n", dev->name, ops->id, ops->argsize, dev->argsize); return -EINVAL; } @@ -505,7 +495,7 @@ static int free_device(struct snd_seq_device *dev, struct ops_list *ops) dev->driver_data = NULL; ops->num_init_devices--; } else { - snd_printk(KERN_ERR "free_device failed: %s: %s\n", + pr_err("ALSA: seq: free_device failed: %s: %s\n", dev->name, dev->id); } @@ -517,18 +507,17 @@ static int free_device(struct snd_seq_device *dev, struct ops_list *ops) */ static struct ops_list * find_driver(char *id, int create_if_empty) { - struct list_head *head; + struct ops_list *ops; - down(&ops_mutex); - list_for_each(head, &opslist) { - struct ops_list *ops = list_entry(head, struct ops_list, list); + mutex_lock(&ops_mutex); + list_for_each_entry(ops, &opslist, list) { if (strcmp(ops->id, id) == 0) { ops->used++; - up(&ops_mutex); + mutex_unlock(&ops_mutex); return ops; } } - up(&ops_mutex); + mutex_unlock(&ops_mutex); if (create_if_empty) return create_driver(id); return NULL; @@ -536,9 +525,9 @@ static struct ops_list * find_driver(char *id, int create_if_empty) static void unlock_driver(struct ops_list *ops) { - down(&ops_mutex); + mutex_lock(&ops_mutex); ops->used--; - up(&ops_mutex); + mutex_unlock(&ops_mutex); } @@ -554,7 +543,6 @@ static int __init alsa_seq_device_init(void) if (info_entry == NULL) return -ENOMEM; info_entry->content = SNDRV_INFO_CONTENT_TEXT; - info_entry->c.text.read_size = 2048; info_entry->c.text.read = snd_seq_device_info; if (snd_info_register(info_entry) < 0) { snd_info_free_entry(info_entry); @@ -568,10 +556,10 @@ static void __exit alsa_seq_device_exit(void) { remove_drivers(); #ifdef CONFIG_PROC_FS - snd_info_unregister(info_entry); + snd_info_free_entry(info_entry); #endif if (num_ops) - snd_printk(KERN_ERR "drivers not released (%d)\n", num_ops); + pr_err("ALSA: seq: drivers not released (%d)\n", num_ops); } module_init(alsa_seq_device_init) @@ -581,7 +569,7 @@ EXPORT_SYMBOL(snd_seq_device_load_drivers); EXPORT_SYMBOL(snd_seq_device_new); EXPORT_SYMBOL(snd_seq_device_register_driver); EXPORT_SYMBOL(snd_seq_device_unregister_driver); -#ifdef CONFIG_KMOD +#ifdef CONFIG_MODULES EXPORT_SYMBOL(snd_seq_autoload_lock); EXPORT_SYMBOL(snd_seq_autoload_unlock); #endif diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c index 2a283a59ea4..ec667f158f1 100644 --- a/sound/core/seq/seq_dummy.c +++ b/sound/core/seq/seq_dummy.c @@ -18,10 +18,9 @@ * */ -#include <sound/driver.h> #include <linux/init.h> #include <linux/slab.h> -#include <linux/moduleparam.h> +#include <linux/module.h> #include <sound/core.h> #include "seq_clientmgr.h" #include <sound/initval.h> @@ -47,11 +46,11 @@ The number of ports to be created can be specified via the module parameter "ports". For example, to create four ports, add the - following option in /etc/modprobe.conf: + following option in a configuration file under /etc/modprobe.d/: option snd-seq-dummy ports=4 - The modle option "duplex=1" enables duplex operation to the port. + The model option "duplex=1" enables duplex operation to the port. In duplex mode, a pair of ports are created instead of single port, and events are tunneled between pair-ports. For example, input to port A is sent to output port of another port B and vice versa. @@ -66,7 +65,7 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS("snd-seq-client-" __stringify(SNDRV_SEQ_CLIENT_DUMMY)); static int ports = 1; -static int duplex = 0; +static bool duplex; module_param(ports, int, 0444); MODULE_PARM_DESC(ports, "number of ports to be created"); @@ -171,7 +170,9 @@ create_port(int idx, int type) pinfo.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; if (duplex) pinfo.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; - pinfo.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; + pinfo.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC + | SNDRV_SEQ_PORT_TYPE_SOFTWARE + | SNDRV_SEQ_PORT_TYPE_PORT; memset(&pcb, 0, sizeof(pcb)); pcb.owner = THIS_MODULE; pcb.unuse = dummy_unuse; @@ -197,7 +198,7 @@ register_client(void) int i; if (ports < 1) { - snd_printk(KERN_ERR "invalid number of ports %d\n", ports); + pr_err("ALSA: seq_dummy: invalid number of ports %d\n", ports); return -EINVAL; } diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c index 6b055aed7a4..53a403e17c5 100644 --- a/sound/core/seq/seq_fifo.c +++ b/sound/core/seq/seq_fifo.c @@ -19,7 +19,6 @@ * */ -#include <sound/driver.h> #include <sound/core.h> #include <linux/slab.h> #include "seq_fifo.h" @@ -35,7 +34,7 @@ struct snd_seq_fifo *snd_seq_fifo_new(int poolsize) f = kzalloc(sizeof(*f), GFP_KERNEL); if (f == NULL) { - snd_printd("malloc failed for snd_seq_fifo_new() \n"); + pr_debug("ALSA: seq: malloc failed for snd_seq_fifo_new() \n"); return NULL; } @@ -66,9 +65,11 @@ void snd_seq_fifo_delete(struct snd_seq_fifo **fifo) { struct snd_seq_fifo *f; - snd_assert(fifo != NULL, return); + if (snd_BUG_ON(!fifo)) + return; f = *fifo; - snd_assert(f != NULL, return); + if (snd_BUG_ON(!f)) + return; *fifo = NULL; snd_seq_fifo_clear(f); @@ -117,12 +118,13 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f, unsigned long flags; int err; - snd_assert(f != NULL, return -EINVAL); + if (snd_BUG_ON(!f)) + return -EINVAL; snd_use_lock_use(&f->use_lock); err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL); /* always non-blocking */ if (err < 0) { - if (err == -ENOMEM) + if ((err == -ENOMEM) || (err == -EAGAIN)) atomic_inc(&f->overflow); snd_use_lock_free(&f->use_lock); return err; @@ -175,7 +177,8 @@ int snd_seq_fifo_cell_out(struct snd_seq_fifo *f, unsigned long flags; wait_queue_t wait; - snd_assert(f != NULL, return -EINVAL); + if (snd_BUG_ON(!f)) + return -EINVAL; *cellp = NULL; init_waitqueue_entry(&wait, current); @@ -234,7 +237,8 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize) struct snd_seq_pool *newpool, *oldpool; struct snd_seq_event_cell *cell, *next, *oldhead; - snd_assert(f != NULL && f->pool != NULL, return -EINVAL); + if (snd_BUG_ON(!f || !f->pool)) + return -EINVAL; /* allocate new pool */ newpool = snd_seq_pool_new(poolsize); diff --git a/sound/core/seq/seq_info.c b/sound/core/seq/seq_info.c index acce21afdaa..acf7769419f 100644 --- a/sound/core/seq/seq_info.c +++ b/sound/core/seq/seq_info.c @@ -19,8 +19,8 @@ * */ -#include <sound/driver.h> #include <linux/init.h> +#include <linux/export.h> #include <sound/core.h> #include "seq_info.h" @@ -34,8 +34,8 @@ static struct snd_info_entry *timer_entry; static struct snd_info_entry * __init -create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *, - struct snd_info_buffer *)) +create_info_entry(char *name, void (*read)(struct snd_info_entry *, + struct snd_info_buffer *)) { struct snd_info_entry *entry; @@ -43,7 +43,6 @@ create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *, if (entry == NULL) return NULL; entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->c.text.read_size = size; entry->c.text.read = read; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); @@ -55,19 +54,19 @@ create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *, /* create all our /proc entries */ int __init snd_seq_info_init(void) { - queues_entry = create_info_entry("queues", 512 + (256 * SNDRV_SEQ_MAX_QUEUES), + queues_entry = create_info_entry("queues", snd_seq_info_queues_read); - clients_entry = create_info_entry("clients", 512 + (256 * SNDRV_SEQ_MAX_CLIENTS), + clients_entry = create_info_entry("clients", snd_seq_info_clients_read); - timer_entry = create_info_entry("timer", 1024, snd_seq_info_timer_read); + timer_entry = create_info_entry("timer", snd_seq_info_timer_read); return 0; } int __exit snd_seq_info_done(void) { - snd_info_unregister(queues_entry); - snd_info_unregister(clients_entry); - snd_info_unregister(timer_entry); + snd_info_free_entry(queues_entry); + snd_info_free_entry(clients_entry); + snd_info_free_entry(timer_entry); return 0; } #endif diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c deleted file mode 100644 index 48745206396..00000000000 --- a/sound/core/seq/seq_instr.c +++ /dev/null @@ -1,653 +0,0 @@ -/* - * Generic Instrument routines for ALSA sequencer - * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz> - * - * 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 <sound/driver.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <sound/core.h> -#include "seq_clientmgr.h" -#include <sound/seq_instr.h> -#include <sound/initval.h> - -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); -MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer instrument library."); -MODULE_LICENSE("GPL"); - - -static void snd_instr_lock_ops(struct snd_seq_kinstr_list *list) -{ - if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) { - spin_lock_irqsave(&list->ops_lock, list->ops_flags); - } else { - down(&list->ops_mutex); - } -} - -static void snd_instr_unlock_ops(struct snd_seq_kinstr_list *list) -{ - if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) { - spin_unlock_irqrestore(&list->ops_lock, list->ops_flags); - } else { - up(&list->ops_mutex); - } -} - -static struct snd_seq_kinstr *snd_seq_instr_new(int add_len, int atomic) -{ - struct snd_seq_kinstr *instr; - - instr = kzalloc(sizeof(struct snd_seq_kinstr) + add_len, atomic ? GFP_ATOMIC : GFP_KERNEL); - if (instr == NULL) - return NULL; - instr->add_len = add_len; - return instr; -} - -static int snd_seq_instr_free(struct snd_seq_kinstr *instr, int atomic) -{ - int result = 0; - - if (instr == NULL) - return -EINVAL; - if (instr->ops && instr->ops->remove) - result = instr->ops->remove(instr->ops->private_data, instr, 1); - if (!result) - kfree(instr); - return result; -} - -struct snd_seq_kinstr_list *snd_seq_instr_list_new(void) -{ - struct snd_seq_kinstr_list *list; - - list = kzalloc(sizeof(struct snd_seq_kinstr_list), GFP_KERNEL); - if (list == NULL) - return NULL; - spin_lock_init(&list->lock); - spin_lock_init(&list->ops_lock); - init_MUTEX(&list->ops_mutex); - list->owner = -1; - return list; -} - -void snd_seq_instr_list_free(struct snd_seq_kinstr_list **list_ptr) -{ - struct snd_seq_kinstr_list *list; - struct snd_seq_kinstr *instr; - struct snd_seq_kcluster *cluster; - int idx; - unsigned long flags; - - if (list_ptr == NULL) - return; - list = *list_ptr; - *list_ptr = NULL; - if (list == NULL) - return; - - for (idx = 0; idx < SNDRV_SEQ_INSTR_HASH_SIZE; idx++) { - while ((instr = list->hash[idx]) != NULL) { - list->hash[idx] = instr->next; - list->count--; - spin_lock_irqsave(&list->lock, flags); - while (instr->use) { - spin_unlock_irqrestore(&list->lock, flags); - schedule_timeout_interruptible(1); - spin_lock_irqsave(&list->lock, flags); - } - spin_unlock_irqrestore(&list->lock, flags); - if (snd_seq_instr_free(instr, 0)<0) - snd_printk(KERN_WARNING "instrument free problem\n"); - } - while ((cluster = list->chash[idx]) != NULL) { - list->chash[idx] = cluster->next; - list->ccount--; - kfree(cluster); - } - } - kfree(list); -} - -static int instr_free_compare(struct snd_seq_kinstr *instr, - struct snd_seq_instr_header *ifree, - unsigned int client) -{ - switch (ifree->cmd) { - case SNDRV_SEQ_INSTR_FREE_CMD_ALL: - /* all, except private for other clients */ - if ((instr->instr.std & 0xff000000) == 0) - return 0; - if (((instr->instr.std >> 24) & 0xff) == client) - return 0; - return 1; - case SNDRV_SEQ_INSTR_FREE_CMD_PRIVATE: - /* all my private instruments */ - if ((instr->instr.std & 0xff000000) == 0) - return 1; - if (((instr->instr.std >> 24) & 0xff) == client) - return 0; - return 1; - case SNDRV_SEQ_INSTR_FREE_CMD_CLUSTER: - /* all my private instruments */ - if ((instr->instr.std & 0xff000000) == 0) { - if (instr->instr.cluster == ifree->id.cluster) - return 0; - return 1; - } - if (((instr->instr.std >> 24) & 0xff) == client) { - if (instr->instr.cluster == ifree->id.cluster) - return 0; - } - return 1; - } - return 1; -} - -int snd_seq_instr_list_free_cond(struct snd_seq_kinstr_list *list, - struct snd_seq_instr_header *ifree, - int client, - int atomic) -{ - struct snd_seq_kinstr *instr, *prev, *next, *flist; - int idx; - unsigned long flags; - - snd_instr_lock_ops(list); - for (idx = 0; idx < SNDRV_SEQ_INSTR_HASH_SIZE; idx++) { - spin_lock_irqsave(&list->lock, flags); - instr = list->hash[idx]; - prev = flist = NULL; - while (instr) { - while (instr && instr_free_compare(instr, ifree, (unsigned int)client)) { - prev = instr; - instr = instr->next; - } - if (instr == NULL) - continue; - if (instr->ops && instr->ops->notify) - instr->ops->notify(instr->ops->private_data, instr, SNDRV_SEQ_INSTR_NOTIFY_REMOVE); - next = instr->next; - if (prev == NULL) { - list->hash[idx] = next; - } else { - prev->next = next; - } - list->count--; - instr->next = flist; - flist = instr; - instr = next; - } - spin_unlock_irqrestore(&list->lock, flags); - while (flist) { - instr = flist; - flist = instr->next; - while (instr->use) - schedule_timeout_interruptible(1); - if (snd_seq_instr_free(instr, atomic)<0) - snd_printk(KERN_WARNING "instrument free problem\n"); - instr = next; - } - } - snd_instr_unlock_ops(list); - return 0; -} - -static int compute_hash_instr_key(struct snd_seq_instr *instr) -{ - int result; - - result = instr->bank | (instr->prg << 16); - result += result >> 24; - result += result >> 16; - result += result >> 8; - return result & (SNDRV_SEQ_INSTR_HASH_SIZE-1); -} - -#if 0 -static int compute_hash_cluster_key(snd_seq_instr_cluster_t cluster) -{ - int result; - - result = cluster; - result += result >> 24; - result += result >> 16; - result += result >> 8; - return result & (SNDRV_SEQ_INSTR_HASH_SIZE-1); -} -#endif - -static int compare_instr(struct snd_seq_instr *i1, struct snd_seq_instr *i2, int exact) -{ - if (exact) { - if (i1->cluster != i2->cluster || - i1->bank != i2->bank || - i1->prg != i2->prg) - return 1; - if ((i1->std & 0xff000000) != (i2->std & 0xff000000)) - return 1; - if (!(i1->std & i2->std)) - return 1; - return 0; - } else { - unsigned int client_check; - - if (i2->cluster && i1->cluster != i2->cluster) - return 1; - client_check = i2->std & 0xff000000; - if (client_check) { - if ((i1->std & 0xff000000) != client_check) - return 1; - } else { - if ((i1->std & i2->std) != i2->std) - return 1; - } - return i1->bank != i2->bank || i1->prg != i2->prg; - } -} - -struct snd_seq_kinstr *snd_seq_instr_find(struct snd_seq_kinstr_list *list, - struct snd_seq_instr *instr, - int exact, - int follow_alias) -{ - unsigned long flags; - int depth = 0; - struct snd_seq_kinstr *result; - - if (list == NULL || instr == NULL) - return NULL; - spin_lock_irqsave(&list->lock, flags); - __again: - result = list->hash[compute_hash_instr_key(instr)]; - while (result) { - if (!compare_instr(&result->instr, instr, exact)) { - if (follow_alias && (result->type == SNDRV_SEQ_INSTR_ATYPE_ALIAS)) { - instr = (struct snd_seq_instr *)KINSTR_DATA(result); - if (++depth > 10) - goto __not_found; - goto __again; - } - result->use++; - spin_unlock_irqrestore(&list->lock, flags); - return result; - } - result = result->next; - } - __not_found: - spin_unlock_irqrestore(&list->lock, flags); - return NULL; -} - -void snd_seq_instr_free_use(struct snd_seq_kinstr_list *list, - struct snd_seq_kinstr *instr) -{ - unsigned long flags; - - if (list == NULL || instr == NULL) - return; - spin_lock_irqsave(&list->lock, flags); - if (instr->use <= 0) { - snd_printk(KERN_ERR "free_use: fatal!!! use = %i, name = '%s'\n", instr->use, instr->name); - } else { - instr->use--; - } - spin_unlock_irqrestore(&list->lock, flags); -} - -static struct snd_seq_kinstr_ops *instr_ops(struct snd_seq_kinstr_ops *ops, - char *instr_type) -{ - while (ops) { - if (!strcmp(ops->instr_type, instr_type)) - return ops; - ops = ops->next; - } - return NULL; -} - -static int instr_result(struct snd_seq_event *ev, - int type, int result, - int atomic) -{ - struct snd_seq_event sev; - - memset(&sev, 0, sizeof(sev)); - sev.type = SNDRV_SEQ_EVENT_RESULT; - sev.flags = SNDRV_SEQ_TIME_STAMP_REAL | SNDRV_SEQ_EVENT_LENGTH_FIXED | - SNDRV_SEQ_PRIORITY_NORMAL; - sev.source = ev->dest; - sev.dest = ev->source; - sev.data.result.event = type; - sev.data.result.result = result; -#if 0 - printk("instr result - type = %i, result = %i, queue = %i, source.client:port = %i:%i, dest.client:port = %i:%i\n", - type, result, - sev.queue, - sev.source.client, sev.source.port, - sev.dest.client, sev.dest.port); -#endif - return snd_seq_kernel_client_dispatch(sev.source.client, &sev, atomic, 0); -} - -static int instr_begin(struct snd_seq_kinstr_ops *ops, - struct snd_seq_kinstr_list *list, - struct snd_seq_event *ev, - int atomic, int hop) -{ - unsigned long flags; - - spin_lock_irqsave(&list->lock, flags); - if (list->owner >= 0 && list->owner != ev->source.client) { - spin_unlock_irqrestore(&list->lock, flags); - return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_BEGIN, -EBUSY, atomic); - } - list->owner = ev->source.client; - spin_unlock_irqrestore(&list->lock, flags); - return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_BEGIN, 0, atomic); -} - -static int instr_end(struct snd_seq_kinstr_ops *ops, - struct snd_seq_kinstr_list *list, - struct snd_seq_event *ev, - int atomic, int hop) -{ - unsigned long flags; - - /* TODO: timeout handling */ - spin_lock_irqsave(&list->lock, flags); - if (list->owner == ev->source.client) { - list->owner = -1; - spin_unlock_irqrestore(&list->lock, flags); - return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_END, 0, atomic); - } - spin_unlock_irqrestore(&list->lock, flags); - return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_END, -EINVAL, atomic); -} - -static int instr_info(struct snd_seq_kinstr_ops *ops, - struct snd_seq_kinstr_list *list, - struct snd_seq_event *ev, - int atomic, int hop) -{ - return -ENXIO; -} - -static int instr_format_info(struct snd_seq_kinstr_ops *ops, - struct snd_seq_kinstr_list *list, - struct snd_seq_event *ev, - int atomic, int hop) -{ - return -ENXIO; -} - -static int instr_reset(struct snd_seq_kinstr_ops *ops, - struct snd_seq_kinstr_list *list, - struct snd_seq_event *ev, - int atomic, int hop) -{ - return -ENXIO; -} - -static int instr_status(struct snd_seq_kinstr_ops *ops, - struct snd_seq_kinstr_list *list, - struct snd_seq_event *ev, - int atomic, int hop) -{ - return -ENXIO; -} - -static int instr_put(struct snd_seq_kinstr_ops *ops, - struct snd_seq_kinstr_list *list, - struct snd_seq_event *ev, - int atomic, int hop) -{ - unsigned long flags; - struct snd_seq_instr_header put; - struct snd_seq_kinstr *instr; - int result = -EINVAL, len, key; - - if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARUSR) - goto __return; - - if (ev->data.ext.len < sizeof(struct snd_seq_instr_header)) - goto __return; - if (copy_from_user(&put, (void __user *)ev->data.ext.ptr, - sizeof(struct snd_seq_instr_header))) { - result = -EFAULT; - goto __return; - } - snd_instr_lock_ops(list); - if (put.id.instr.std & 0xff000000) { /* private instrument */ - put.id.instr.std &= 0x00ffffff; - put.id.instr.std |= (unsigned int)ev->source.client << 24; - } - if ((instr = snd_seq_instr_find(list, &put.id.instr, 1, 0))) { - snd_seq_instr_free_use(list, instr); - snd_instr_unlock_ops(list); - result = -EBUSY; - goto __return; - } - ops = instr_ops(ops, put.data.data.format); - if (ops == NULL) { - snd_instr_unlock_ops(list); - goto __return; - } - len = ops->add_len; - if (put.data.type == SNDRV_SEQ_INSTR_ATYPE_ALIAS) - len = sizeof(struct snd_seq_instr); - instr = snd_seq_instr_new(len, atomic); - if (instr == NULL) { - snd_instr_unlock_ops(list); - result = -ENOMEM; - goto __return; - } - instr->ops = ops; - instr->instr = put.id.instr; - strlcpy(instr->name, put.data.name, sizeof(instr->name)); - instr->type = put.data.type; - if (instr->type == SNDRV_SEQ_INSTR_ATYPE_DATA) { - result = ops->put(ops->private_data, - instr, - (void __user *)ev->data.ext.ptr + sizeof(struct snd_seq_instr_header), - ev->data.ext.len - sizeof(struct snd_seq_instr_header), - atomic, - put.cmd); - if (result < 0) { - snd_seq_instr_free(instr, atomic); - snd_instr_unlock_ops(list); - goto __return; - } - } - key = compute_hash_instr_key(&instr->instr); - spin_lock_irqsave(&list->lock, flags); - instr->next = list->hash[key]; - list->hash[key] = instr; - list->count++; - spin_unlock_irqrestore(&list->lock, flags); - snd_instr_unlock_ops(list); - result = 0; - __return: - instr_result(ev, SNDRV_SEQ_EVENT_INSTR_PUT, result, atomic); - return result; -} - -static int instr_get(struct snd_seq_kinstr_ops *ops, - struct snd_seq_kinstr_list *list, - struct snd_seq_event *ev, - int atomic, int hop) -{ - return -ENXIO; -} - -static int instr_free(struct snd_seq_kinstr_ops *ops, - struct snd_seq_kinstr_list *list, - struct snd_seq_event *ev, - int atomic, int hop) -{ - struct snd_seq_instr_header ifree; - struct snd_seq_kinstr *instr, *prev; - int result = -EINVAL; - unsigned long flags; - unsigned int hash; - - if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARUSR) - goto __return; - - if (ev->data.ext.len < sizeof(struct snd_seq_instr_header)) - goto __return; - if (copy_from_user(&ifree, (void __user *)ev->data.ext.ptr, - sizeof(struct snd_seq_instr_header))) { - result = -EFAULT; - goto __return; - } - if (ifree.cmd == SNDRV_SEQ_INSTR_FREE_CMD_ALL || - ifree.cmd == SNDRV_SEQ_INSTR_FREE_CMD_PRIVATE || - ifree.cmd == SNDRV_SEQ_INSTR_FREE_CMD_CLUSTER) { - result = snd_seq_instr_list_free_cond(list, &ifree, ev->dest.client, atomic); - goto __return; - } - if (ifree.cmd == SNDRV_SEQ_INSTR_FREE_CMD_SINGLE) { - if (ifree.id.instr.std & 0xff000000) { - ifree.id.instr.std &= 0x00ffffff; - ifree.id.instr.std |= (unsigned int)ev->source.client << 24; - } - hash = compute_hash_instr_key(&ifree.id.instr); - snd_instr_lock_ops(list); - spin_lock_irqsave(&list->lock, flags); - instr = list->hash[hash]; - prev = NULL; - while (instr) { - if (!compare_instr(&instr->instr, &ifree.id.instr, 1)) - goto __free_single; - prev = instr; - instr = instr->next; - } - result = -ENOENT; - spin_unlock_irqrestore(&list->lock, flags); - snd_instr_unlock_ops(list); - goto __return; - - __free_single: - if (prev) { - prev->next = instr->next; - } else { - list->hash[hash] = instr->next; - } - if (instr->ops && instr->ops->notify) - instr->ops->notify(instr->ops->private_data, instr, - SNDRV_SEQ_INSTR_NOTIFY_REMOVE); - while (instr->use) { - spin_unlock_irqrestore(&list->lock, flags); - schedule_timeout_interruptible(1); - spin_lock_irqsave(&list->lock, flags); - } - spin_unlock_irqrestore(&list->lock, flags); - result = snd_seq_instr_free(instr, atomic); - snd_instr_unlock_ops(list); - goto __return; - } - - __return: - instr_result(ev, SNDRV_SEQ_EVENT_INSTR_FREE, result, atomic); - return result; -} - -static int instr_list(struct snd_seq_kinstr_ops *ops, - struct snd_seq_kinstr_list *list, - struct snd_seq_event *ev, - int atomic, int hop) -{ - return -ENXIO; -} - -static int instr_cluster(struct snd_seq_kinstr_ops *ops, - struct snd_seq_kinstr_list *list, - struct snd_seq_event *ev, - int atomic, int hop) -{ - return -ENXIO; -} - -int snd_seq_instr_event(struct snd_seq_kinstr_ops *ops, - struct snd_seq_kinstr_list *list, - struct snd_seq_event *ev, - int client, - int atomic, - int hop) -{ - int direct = 0; - - snd_assert(ops != NULL && list != NULL && ev != NULL, return -EINVAL); - if (snd_seq_ev_is_direct(ev)) { - direct = 1; - switch (ev->type) { - case SNDRV_SEQ_EVENT_INSTR_BEGIN: - return instr_begin(ops, list, ev, atomic, hop); - case SNDRV_SEQ_EVENT_INSTR_END: - return instr_end(ops, list, ev, atomic, hop); - } - } - if ((list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT) && !direct) - return -EINVAL; - switch (ev->type) { - case SNDRV_SEQ_EVENT_INSTR_INFO: - return instr_info(ops, list, ev, atomic, hop); - case SNDRV_SEQ_EVENT_INSTR_FINFO: - return instr_format_info(ops, list, ev, atomic, hop); - case SNDRV_SEQ_EVENT_INSTR_RESET: - return instr_reset(ops, list, ev, atomic, hop); - case SNDRV_SEQ_EVENT_INSTR_STATUS: - return instr_status(ops, list, ev, atomic, hop); - case SNDRV_SEQ_EVENT_INSTR_PUT: - return instr_put(ops, list, ev, atomic, hop); - case SNDRV_SEQ_EVENT_INSTR_GET: - return instr_get(ops, list, ev, atomic, hop); - case SNDRV_SEQ_EVENT_INSTR_FREE: - return instr_free(ops, list, ev, atomic, hop); - case SNDRV_SEQ_EVENT_INSTR_LIST: - return instr_list(ops, list, ev, atomic, hop); - case SNDRV_SEQ_EVENT_INSTR_CLUSTER: - return instr_cluster(ops, list, ev, atomic, hop); - } - return -EINVAL; -} - -/* - * Init part - */ - -static int __init alsa_seq_instr_init(void) -{ - return 0; -} - -static void __exit alsa_seq_instr_exit(void) -{ -} - -module_init(alsa_seq_instr_init) -module_exit(alsa_seq_instr_exit) - -EXPORT_SYMBOL(snd_seq_instr_list_new); -EXPORT_SYMBOL(snd_seq_instr_list_free); -EXPORT_SYMBOL(snd_seq_instr_list_free_cond); -EXPORT_SYMBOL(snd_seq_instr_find); -EXPORT_SYMBOL(snd_seq_instr_free_use); -EXPORT_SYMBOL(snd_seq_instr_event); diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c index a837a94b2d2..3b693e924db 100644 --- a/sound/core/seq/seq_lock.c +++ b/sound/core/seq/seq_lock.c @@ -19,7 +19,7 @@ * */ -#include <sound/driver.h> +#include <linux/export.h> #include <sound/core.h> #include "seq_lock.h" @@ -31,12 +31,12 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) int max_count = 5 * HZ; if (atomic_read(lockp) < 0) { - printk(KERN_WARNING "seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line); + pr_warn("ALSA: seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line); return; } while (atomic_read(lockp) > 0) { if (max_count == 0) { - snd_printk(KERN_WARNING "seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line); + pr_warn("ALSA: seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line); break; } schedule_timeout_uninterruptible(1); @@ -44,4 +44,6 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) } } +EXPORT_SYMBOL(snd_use_lock_sync_helper); + #endif diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index 40b4f679c80..1e206de0c2d 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c @@ -1,7 +1,7 @@ /* * ALSA sequencer Memory Manager * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl> - * Jaroslav Kysela <perex@suse.cz> + * Jaroslav Kysela <perex@perex.cz> * 2000 by Takashi Iwai <tiwai@suse.de> * * This program is free software; you can redistribute it and/or modify @@ -20,8 +20,8 @@ * */ -#include <sound/driver.h> #include <linux/init.h> +#include <linux/export.h> #include <linux/slab.h> #include <linux/vmalloc.h> #include <sound/core.h> @@ -87,7 +87,7 @@ int snd_seq_dump_var_event(const struct snd_seq_event *event, if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) { char buf[32]; - char __user *curptr = (char __user *)event->data.ext.ptr; + char __user *curptr = (char __force __user *)event->data.ext.ptr; while (len > 0) { int size = sizeof(buf); if (len < size) @@ -118,6 +118,8 @@ int snd_seq_dump_var_event(const struct snd_seq_event *event, return 0; } +EXPORT_SYMBOL(snd_seq_dump_var_event); + /* * exported: @@ -149,14 +151,14 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char return len; newlen = len; if (size_aligned > 0) - newlen = ((len + size_aligned - 1) / size_aligned) * size_aligned; + newlen = roundup(len, size_aligned); if (count < newlen) return -EAGAIN; if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) { if (! in_kernel) return -EINVAL; - if (copy_from_user(buf, (void __user *)event->data.ext.ptr, len)) + if (copy_from_user(buf, (void __force __user *)event->data.ext.ptr, len)) return -EFAULT; return newlen; } @@ -167,6 +169,7 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char return err < 0 ? err : newlen; } +EXPORT_SYMBOL(snd_seq_expand_var_event); /* * release this cell, free extended data if available @@ -185,9 +188,11 @@ void snd_seq_cell_free(struct snd_seq_event_cell * cell) unsigned long flags; struct snd_seq_pool *pool; - snd_assert(cell != NULL, return); + if (snd_BUG_ON(!cell)) + return; pool = cell->pool; - snd_assert(pool != NULL, return); + if (snd_BUG_ON(!pool)) + return; spin_lock_irqsave(&pool->lock, flags); free_cell(pool, cell); @@ -231,7 +236,7 @@ static int snd_seq_cell_alloc(struct snd_seq_pool *pool, init_waitqueue_entry(&wait, current); spin_lock_irqsave(&pool->lock, flags); if (pool->ptr == NULL) { /* not initialized */ - snd_printd("seq: pool is not initialized\n"); + pr_debug("ALSA: seq: pool is not initialized\n"); err = -EINVAL; goto __error; } @@ -339,7 +344,7 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event, tmp->event = src->event; src = src->next; } else if (is_usrptr) { - if (copy_from_user(&tmp->event, (char __user *)buf, size)) { + if (copy_from_user(&tmp->event, (char __force __user *)buf, size)) { err = -EFAULT; goto __error; } @@ -376,13 +381,14 @@ int snd_seq_pool_init(struct snd_seq_pool *pool) struct snd_seq_event_cell *cellptr; unsigned long flags; - snd_assert(pool != NULL, return -EINVAL); + if (snd_BUG_ON(!pool)) + return -EINVAL; if (pool->ptr) /* should be atomic? */ return 0; pool->ptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size); if (pool->ptr == NULL) { - snd_printd("seq: malloc for sequencer events failed\n"); + pr_debug("ALSA: seq: malloc for sequencer events failed\n"); return -ENOMEM; } @@ -412,7 +418,8 @@ int snd_seq_pool_done(struct snd_seq_pool *pool) struct snd_seq_event_cell *ptr; int max_count = 5 * HZ; - snd_assert(pool != NULL, return -EINVAL); + if (snd_BUG_ON(!pool)) + return -EINVAL; /* wait for closing all threads */ spin_lock_irqsave(&pool->lock, flags); @@ -424,7 +431,7 @@ int snd_seq_pool_done(struct snd_seq_pool *pool) while (atomic_read(&pool->counter) > 0) { if (max_count == 0) { - snd_printk(KERN_WARNING "snd_seq_pool_done timeout: %d cells remain\n", atomic_read(&pool->counter)); + pr_warn("ALSA: snd_seq_pool_done timeout: %d cells remain\n", atomic_read(&pool->counter)); break; } schedule_timeout_uninterruptible(1); @@ -457,7 +464,7 @@ struct snd_seq_pool *snd_seq_pool_new(int poolsize) /* create pool block */ pool = kzalloc(sizeof(*pool), GFP_KERNEL); if (pool == NULL) { - snd_printd("seq: malloc failed for pool\n"); + pr_debug("ALSA: seq: malloc failed for pool\n"); return NULL; } spin_lock_init(&pool->lock); diff --git a/sound/core/seq/seq_memory.h b/sound/core/seq/seq_memory.h index 39c60d9e1ef..4a2ec779b8a 100644 --- a/sound/core/seq/seq_memory.h +++ b/sound/core/seq/seq_memory.h @@ -24,6 +24,8 @@ #include <sound/seq_kernel.h> #include <linux/poll.h> +struct snd_info_buffer; + /* container for sequencer event (internal use) */ struct snd_seq_event_cell { struct snd_seq_event event; @@ -31,7 +33,7 @@ struct snd_seq_event_cell { struct snd_seq_event_cell *next; /* next cell */ }; -/* design note: the pool is a contigious block of memory, if we dynamicly +/* design note: the pool is a contiguous block of memory, if we dynamicly want to add additional cells to the pool be better store this in another pool as we need to know the base address of the pool when releasing memory. */ @@ -99,5 +101,7 @@ void snd_sequencer_memory_done(void); /* polling */ int snd_seq_pool_poll_wait(struct snd_seq_pool *pool, struct file *file, poll_table *wait); +void snd_seq_info_pool(struct snd_info_buffer *buffer, + struct snd_seq_pool *pool, char *space); #endif diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index ce0df86157d..a1fd77af605 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c @@ -1,7 +1,7 @@ /* * Generic MIDI synth driver for ALSA sequencer * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl> - * Jaroslav Kysela <perex@suse.cz> + * Jaroslav Kysela <perex@perex.cz> * * 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 @@ -26,13 +26,12 @@ Possible options for midisynth module: */ -#include <sound/driver.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/string.h> -#include <linux/moduleparam.h> -#include <asm/semaphore.h> +#include <linux/module.h> +#include <linux/mutex.h> #include <sound/core.h> #include <sound/rawmidi.h> #include <sound/seq_kernel.h> @@ -40,7 +39,7 @@ Possible options for midisynth module: #include <sound/seq_midi_event.h> #include <sound/initval.h> -MODULE_AUTHOR("Frank van de Pol <fvdpol@coil.demon.nl>, Jaroslav Kysela <perex@suse.cz>"); +MODULE_AUTHOR("Frank van de Pol <fvdpol@coil.demon.nl>, Jaroslav Kysela <perex@perex.cz>"); MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer MIDI synth."); MODULE_LICENSE("GPL"); static int output_buffer_size = PAGE_SIZE; @@ -70,7 +69,7 @@ struct seq_midisynth_client { }; static struct seq_midisynth_client *synths[SNDRV_CARDS]; -static DECLARE_MUTEX(register_mutex); +static DEFINE_MUTEX(register_mutex); /* handle rawmidi input event (MIDI v1.0 stream) */ static void snd_midi_input_event(struct snd_rawmidi_substream *substream) @@ -117,10 +116,12 @@ static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, i struct snd_rawmidi_runtime *runtime; int tmp; - snd_assert(substream != NULL || buf != NULL, return -EINVAL); + if (snd_BUG_ON(!substream || !buf)) + return -EINVAL; runtime = substream->runtime; if ((tmp = runtime->avail) < count) { - snd_printd("warning, output event was lost (count = %i, available = %i)\n", count, tmp); + if (printk_ratelimit()) + pr_err("ALSA: seq_midi: MIDI output buffer overrun\n"); return -ENOMEM; } if (snd_rawmidi_kernel_write(substream, buf, count) < count) @@ -136,14 +137,15 @@ static int event_process_midi(struct snd_seq_event *ev, int direct, struct snd_rawmidi_substream *substream; int len; - snd_assert(msynth != NULL, return -EINVAL); + if (snd_BUG_ON(!msynth)) + return -EINVAL; substream = msynth->output_rfile.output; if (substream == NULL) return -ENODEV; if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { /* special case, to save space */ if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) { /* invalid event */ - snd_printd("seq_midi: invalid sysex event flags = 0x%x\n", ev->flags); + pr_debug("ALSA: seq_midi: invalid sysex event flags = 0x%x\n", ev->flags); return 0; } snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream); @@ -187,7 +189,7 @@ static int midisynth_subscribe(void *private_data, struct snd_seq_port_subscribe msynth->subdevice, SNDRV_RAWMIDI_LFLG_INPUT, &msynth->input_rfile)) < 0) { - snd_printd("midi input open failed!!!\n"); + pr_debug("ALSA: seq_midi: midi input open failed!!!\n"); return err; } runtime = msynth->input_rfile.input->runtime; @@ -211,7 +213,8 @@ static int midisynth_unsubscribe(void *private_data, struct snd_seq_port_subscri int err; struct seq_midisynth *msynth = private_data; - snd_assert(msynth->input_rfile.input != NULL, return -EINVAL); + if (snd_BUG_ON(!msynth->input_rfile.input)) + return -EINVAL; err = snd_rawmidi_kernel_release(&msynth->input_rfile); return err; } @@ -228,12 +231,13 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info msynth->subdevice, SNDRV_RAWMIDI_LFLG_OUTPUT, &msynth->output_rfile)) < 0) { - snd_printd("midi output open failed!!!\n"); + pr_debug("ALSA: seq_midi: midi output open failed!!!\n"); return err; } memset(¶ms, 0, sizeof(params)); params.avail_min = 1; params.buffer_size = output_buffer_size; + params.no_active_sensing = 1; if ((err = snd_rawmidi_output_params(msynth->output_rfile.output, ¶ms)) < 0) { snd_rawmidi_kernel_release(&msynth->output_rfile); return err; @@ -246,11 +250,9 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info static int midisynth_unuse(void *private_data, struct snd_seq_port_subscribe *info) { struct seq_midisynth *msynth = private_data; - unsigned char buf = 0xff; /* MIDI reset */ - snd_assert(msynth->output_rfile.output != NULL, return -EINVAL); - /* sending single MIDI reset message to shut the device up */ - snd_rawmidi_kernel_write(msynth->output_rfile.output, &buf, 1); + if (snd_BUG_ON(!msynth->output_rfile.output)) + return -EINVAL; snd_rawmidi_drain_output(msynth->output_rfile.output); return snd_rawmidi_kernel_release(&msynth->output_rfile); } @@ -278,6 +280,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) struct seq_midisynth *msynth, *ms; struct snd_seq_port_info *port; struct snd_rawmidi_info *info; + struct snd_rawmidi *rmidi = dev->private_data; int newclient = 0; unsigned int p, ports; struct snd_seq_port_callback pcallbacks; @@ -285,7 +288,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) int device = dev->device; unsigned int input_count = 0, output_count = 0; - snd_assert(card != NULL && device >= 0 && device < SNDRV_RAWMIDI_DEVICES, return -EINVAL); + if (snd_BUG_ON(!card || device < 0 || device >= SNDRV_RAWMIDI_DEVICES)) + return -EINVAL; info = kmalloc(sizeof(*info), GFP_KERNEL); if (! info) return -ENOMEM; @@ -308,23 +312,23 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) if (ports > (256 / SNDRV_RAWMIDI_DEVICES)) ports = 256 / SNDRV_RAWMIDI_DEVICES; - down(®ister_mutex); + mutex_lock(®ister_mutex); client = synths[card->number]; if (client == NULL) { newclient = 1; client = kzalloc(sizeof(*client), GFP_KERNEL); if (client == NULL) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); kfree(info); return -ENOMEM; } client->seq_client = snd_seq_create_kernel_client( - card, 0, "%s", info->name[0] ? - (const char *)info->name : "External MIDI"); + card, 0, "%s", card->shortname[0] ? + (const char *)card->shortname : "External MIDI"); if (client->seq_client < 0) { kfree(client); - up(®ister_mutex); + mutex_unlock(®ister_mutex); kfree(info); return -ENOMEM; } @@ -358,13 +362,13 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) if (! port->name[0]) { if (info->name[0]) { if (ports > 1) - snprintf(port->name, sizeof(port->name), "%s-%d", info->name, p); + snprintf(port->name, sizeof(port->name), "%s-%u", info->name, p); else snprintf(port->name, sizeof(port->name), "%s", info->name); } else { /* last resort */ if (ports > 1) - sprintf(port->name, "MIDI %d-%d-%d", card->number, device, p); + sprintf(port->name, "MIDI %d-%d-%u", card->number, device, p); else sprintf(port->name, "MIDI %d-%d", card->number, device); } @@ -376,7 +380,9 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) if ((port->capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) && info->flags & SNDRV_RAWMIDI_INFO_DUPLEX) port->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; - port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; + port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC + | SNDRV_SEQ_PORT_TYPE_HARDWARE + | SNDRV_SEQ_PORT_TYPE_PORT; port->midi_channels = 16; memset(&pcallbacks, 0, sizeof(pcallbacks)); pcallbacks.owner = THIS_MODULE; @@ -387,6 +393,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) pcallbacks.unuse = midisynth_unuse; pcallbacks.event_input = event_process_midi; port->kernel = &pcallbacks; + if (rmidi->ops && rmidi->ops->get_port_info) + rmidi->ops->get_port_info(rmidi, p, port); if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, port)<0) goto __nomem; ms->seq_client = client->seq_client; @@ -397,7 +405,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) client->num_ports++; if (newclient) synths[card->number] = client; - up(®ister_mutex); + mutex_unlock(®ister_mutex); kfree(info); kfree(port); return 0; /* success */ @@ -414,7 +422,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) } kfree(info); kfree(port); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -ENOMEM; } @@ -427,10 +435,10 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev) struct snd_card *card = dev->card; int device = dev->device, p, ports; - down(®ister_mutex); + mutex_lock(®ister_mutex); client = synths[card->number]; if (client == NULL || client->ports[device] == NULL) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -ENODEV; } ports = client->ports_per_device[device]; @@ -446,7 +454,7 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev) synths[card->number] = NULL; kfree(client); } - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } diff --git a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c index d7c4fb86b9e..9b6470cdcf2 100644 --- a/sound/core/seq/seq_midi_emul.c +++ b/sound/core/seq/seq_midi_emul.c @@ -29,10 +29,10 @@ * code in here. If there is it should be reported as a bug. */ -#include <sound/driver.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/string.h> +#include <linux/module.h> #include <sound/core.h> #include <sound/seq_kernel.h> #include <sound/seq_midi_emul.h> @@ -71,7 +71,7 @@ static void reset_all_channels(struct snd_midi_channel_set *chset); * such as GM, GS and XG. * There modes that this module will run in are: * Generic MIDI - no interpretation at all, it will just save current values - * of controlers etc. + * of controllers etc. * GM - You can use all gm_ prefixed elements of chan. Controls, RPN, NRPN, * SysEx will be interpreded as defined in General Midi. * GS - You can use all gs_ prefixed elements of chan. Codes for GS will be @@ -89,7 +89,7 @@ snd_midi_process_event(struct snd_midi_op *ops, int dest_channel = 0; if (ev == NULL || chanset == NULL) { - snd_printd("ev or chanbase NULL (snd_midi_process_event)\n"); + pr_debug("ALSA: seq_midi_emul: ev or chanbase NULL (snd_midi_process_event)\n"); return; } if (chanset->channels == NULL) @@ -98,7 +98,7 @@ snd_midi_process_event(struct snd_midi_op *ops, if (snd_seq_ev_is_channel_type(ev)) { dest_channel = ev->data.note.channel; if (dest_channel >= chanset->max_channels) { - snd_printd("dest channel is %d, max is %d\n", + pr_debug("ALSA: seq_midi_emul: dest channel is %d, max is %d\n", dest_channel, chanset->max_channels); return; } @@ -176,7 +176,7 @@ snd_midi_process_event(struct snd_midi_op *ops, ev->data.control.value); break; case SNDRV_SEQ_EVENT_NONREGPARAM: - /* Break it back into its controler values */ + /* Break it back into its controller values */ chan->param_type = SNDRV_MIDI_PARAM_TYPE_NONREGISTERED; chan->control[MIDI_CTL_MSB_DATA_ENTRY] = (ev->data.control.value >> 7) & 0x7f; @@ -189,7 +189,7 @@ snd_midi_process_event(struct snd_midi_op *ops, nrpn(ops, drv, chan, chanset); break; case SNDRV_SEQ_EVENT_REGPARAM: - /* Break it back into its controler values */ + /* Break it back into its controller values */ chan->param_type = SNDRV_MIDI_PARAM_TYPE_REGISTERED; chan->control[MIDI_CTL_MSB_DATA_ENTRY] = (ev->data.control.value >> 7) & 0x7f; @@ -229,17 +229,10 @@ snd_midi_process_event(struct snd_midi_op *ops, case SNDRV_SEQ_EVENT_PORT_START: case SNDRV_SEQ_EVENT_PORT_EXIT: case SNDRV_SEQ_EVENT_PORT_CHANGE: - case SNDRV_SEQ_EVENT_SAMPLE: - case SNDRV_SEQ_EVENT_SAMPLE_START: - case SNDRV_SEQ_EVENT_SAMPLE_STOP: - case SNDRV_SEQ_EVENT_SAMPLE_FREQ: - case SNDRV_SEQ_EVENT_SAMPLE_VOLUME: - case SNDRV_SEQ_EVENT_SAMPLE_LOOP: - case SNDRV_SEQ_EVENT_SAMPLE_POSITION: case SNDRV_SEQ_EVENT_ECHO: not_yet: default: - /*snd_printd("Unimplemented event %d\n", ev->type);*/ + /*pr_debug("ALSA: seq_midi_emul: Unimplemented event %d\n", ev->type);*/ break; } } @@ -267,7 +260,7 @@ note_off(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan, } /* - * Do all driver independent operations for this controler and pass + * Do all driver independent operations for this controller and pass * events that need to take place immediately to the driver. */ static void diff --git a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c index 5ff80b77690..37db7ba492a 100644 --- a/sound/core/seq/seq_midi_event.c +++ b/sound/core/seq/seq_midi_event.c @@ -2,7 +2,7 @@ * MIDI byte <-> sequencer event coder * * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>, - * Jaroslav Kysela <perex@suse.cz> + * Jaroslav Kysela <perex@perex.cz> * * 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 @@ -19,23 +19,22 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <sound/driver.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/string.h> +#include <linux/module.h> #include <sound/core.h> #include <sound/seq_kernel.h> #include <sound/seq_midi_event.h> #include <sound/asoundef.h> -MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@suse.cz>"); +MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>"); MODULE_DESCRIPTION("MIDI byte <-> sequencer event coder"); MODULE_LICENSE("GPL"); -/* queue type */ -/* from 0 to 7 are normal commands (note off, on, etc.) */ -#define ST_NOTEOFF 0 -#define ST_NOTEON 1 +/* event type, index into status_event[] */ +/* from 0 to 6 are normal commands (note off, on, etc.) for 0x9?-0xe? */ +#define ST_INVALID 7 #define ST_SPECIAL 8 #define ST_SYSEX ST_SPECIAL /* from 8 to 15 are events for 0xf0-0xf7 */ @@ -65,32 +64,33 @@ static struct status_event_list { void (*encode)(struct snd_midi_event *dev, struct snd_seq_event *ev); void (*decode)(struct snd_seq_event *ev, unsigned char *buf); } status_event[] = { - /* 0x80 - 0xf0 */ - {SNDRV_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode}, - {SNDRV_SEQ_EVENT_NOTEON, 2, note_event, note_decode}, - {SNDRV_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode}, - {SNDRV_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode}, - {SNDRV_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode}, - {SNDRV_SEQ_EVENT_CHANPRESS, 1, one_param_ctrl_event, one_param_decode}, - {SNDRV_SEQ_EVENT_PITCHBEND, 2, pitchbend_ctrl_event, pitchbend_decode}, - {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf0 */ + /* 0x80 - 0xef */ + {SNDRV_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode}, + {SNDRV_SEQ_EVENT_NOTEON, 2, note_event, note_decode}, + {SNDRV_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode}, + {SNDRV_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode}, + {SNDRV_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode}, + {SNDRV_SEQ_EVENT_CHANPRESS, 1, one_param_ctrl_event, one_param_decode}, + {SNDRV_SEQ_EVENT_PITCHBEND, 2, pitchbend_ctrl_event, pitchbend_decode}, + /* invalid */ + {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf0 - 0xff */ - {SNDRV_SEQ_EVENT_SYSEX, 1, NULL, NULL}, /* sysex: 0xf0 */ - {SNDRV_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */ - {SNDRV_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */ - {SNDRV_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */ - {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf4 */ - {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf5 */ - {SNDRV_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL}, /* 0xf6 */ - {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf7 */ - {SNDRV_SEQ_EVENT_CLOCK, 0, NULL, NULL}, /* 0xf8 */ - {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf9 */ - {SNDRV_SEQ_EVENT_START, 0, NULL, NULL}, /* 0xfa */ - {SNDRV_SEQ_EVENT_CONTINUE, 0, NULL, NULL}, /* 0xfb */ - {SNDRV_SEQ_EVENT_STOP, 0, NULL, NULL}, /* 0xfc */ - {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xfd */ - {SNDRV_SEQ_EVENT_SENSING, 0, NULL, NULL}, /* 0xfe */ - {SNDRV_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */ + {SNDRV_SEQ_EVENT_SYSEX, 1, NULL, NULL}, /* sysex: 0xf0 */ + {SNDRV_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */ + {SNDRV_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */ + {SNDRV_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */ + {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf4 */ + {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf5 */ + {SNDRV_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL}, /* 0xf6 */ + {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf7 */ + {SNDRV_SEQ_EVENT_CLOCK, 0, NULL, NULL}, /* 0xf8 */ + {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf9 */ + {SNDRV_SEQ_EVENT_START, 0, NULL, NULL}, /* 0xfa */ + {SNDRV_SEQ_EVENT_CONTINUE, 0, NULL, NULL}, /* 0xfb */ + {SNDRV_SEQ_EVENT_STOP, 0, NULL, NULL}, /* 0xfc */ + {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xfd */ + {SNDRV_SEQ_EVENT_SENSING, 0, NULL, NULL}, /* 0xfe */ + {SNDRV_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */ }; static int extra_decode_ctrl14(struct snd_midi_event *dev, unsigned char *buf, int len, @@ -129,6 +129,7 @@ int snd_midi_event_new(int bufsize, struct snd_midi_event **rdev) } dev->bufsize = bufsize; dev->lastcmd = 0xff; + dev->type = ST_INVALID; spin_lock_init(&dev->lock); *rdev = dev; return 0; @@ -149,7 +150,7 @@ static inline void reset_encode(struct snd_midi_event *dev) { dev->read = 0; dev->qlen = 0; - dev->type = 0; + dev->type = ST_INVALID; } void snd_midi_event_reset_encode(struct snd_midi_event *dev) @@ -251,29 +252,31 @@ int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c, ev->type = status_event[ST_SPECIAL + c - 0xf0].event; ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK; ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED; - return 1; + return ev->type != SNDRV_SEQ_EVENT_NONE; } spin_lock_irqsave(&dev->lock, flags); - if (dev->qlen > 0) { - /* rest of command */ - dev->buf[dev->read++] = c; - if (dev->type != ST_SYSEX) - dev->qlen--; - } else { + if ((c & 0x80) && + (c != MIDI_CMD_COMMON_SYSEX_END || dev->type != ST_SYSEX)) { /* new command */ + dev->buf[0] = c; + if ((c & 0xf0) == 0xf0) /* system messages */ + dev->type = (c & 0x0f) + ST_SPECIAL; + else + dev->type = (c >> 4) & 0x07; dev->read = 1; - if (c & 0x80) { - dev->buf[0] = c; - if ((c & 0xf0) == 0xf0) /* special events */ - dev->type = (c & 0x0f) + ST_SPECIAL; - else - dev->type = (c >> 4) & 0x07; - dev->qlen = status_event[dev->type].qlen; - } else { - /* process this byte as argument */ + dev->qlen = status_event[dev->type].qlen; + } else { + if (dev->qlen > 0) { + /* rest of command */ dev->buf[dev->read++] = c; + if (dev->type != ST_SYSEX) + dev->qlen--; + } else { + /* running status */ + dev->buf[1] = c; dev->qlen = status_event[dev->type].qlen - 1; + dev->read = 2; } } if (dev->qlen == 0) { @@ -282,6 +285,8 @@ int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c, ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED; if (status_event[dev->type].encode) /* set data values */ status_event[dev->type].encode(dev, ev); + if (dev->type >= ST_SPECIAL) + dev->type = ST_INVALID; rc = 1; } else if (dev->type == ST_SYSEX) { if (c == MIDI_CMD_COMMON_SYSEX_END || @@ -500,10 +505,10 @@ static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf, if (dev->nostat && count < 12) return -ENOMEM; cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f); - bytes[0] = ev->data.control.param & 0x007f; - bytes[1] = (ev->data.control.param & 0x3f80) >> 7; - bytes[2] = ev->data.control.value & 0x007f; - bytes[3] = (ev->data.control.value & 0x3f80) >> 7; + bytes[0] = (ev->data.control.param & 0x3f80) >> 7; + bytes[1] = ev->data.control.param & 0x007f; + bytes[2] = (ev->data.control.value & 0x3f80) >> 7; + bytes[3] = ev->data.control.value & 0x007f; if (cmd != dev->lastcmd && !dev->nostat) { if (count < 9) return -ENOMEM; diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index 2b384fd7967..794a341bf0e 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c @@ -1,7 +1,7 @@ /* * ALSA sequencer Ports * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl> - * Jaroslav Kysela <perex@suse.cz> + * Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -20,9 +20,9 @@ * */ -#include <sound/driver.h> #include <sound/core.h> #include <linux/slab.h> +#include <linux/module.h> #include "seq_system.h" #include "seq_ports.h" #include "seq_clientmgr.h" @@ -59,14 +59,12 @@ much elements are in array. struct snd_seq_client_port *snd_seq_port_use_ptr(struct snd_seq_client *client, int num) { - struct list_head *p; struct snd_seq_client_port *port; if (client == NULL) return NULL; read_lock(&client->ports_lock); - list_for_each(p, &client->ports_list_head) { - port = list_entry(p, struct snd_seq_client_port, list); + list_for_each_entry(port, &client->ports_list_head, list) { if (port->addr.port == num) { if (port->closing) break; /* deleting now */ @@ -85,14 +83,12 @@ struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *cl struct snd_seq_port_info *pinfo) { int num; - struct list_head *p; struct snd_seq_client_port *port, *found; num = pinfo->addr.port; found = NULL; read_lock(&client->ports_lock); - list_for_each(p, &client->ports_list_head) { - port = list_entry(p, struct snd_seq_client_port, list); + list_for_each_entry(port, &client->ports_list_head, list) { if (port->addr.port < num) continue; if (port->addr.port == num) { @@ -131,22 +127,22 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, int port) { unsigned long flags; - struct snd_seq_client_port *new_port; - struct list_head *l; + struct snd_seq_client_port *new_port, *p; int num = -1; /* sanity check */ - snd_assert(client, return NULL); + if (snd_BUG_ON(!client)) + return NULL; if (client->num_ports >= SNDRV_SEQ_MAX_PORTS - 1) { - snd_printk(KERN_WARNING "too many ports for client %d\n", client->number); + pr_warn("ALSA: seq: too many ports for client %d\n", client->number); return NULL; } /* create a new port */ new_port = kzalloc(sizeof(*new_port), GFP_KERNEL); if (! new_port) { - snd_printd("malloc failed for registering client port\n"); + pr_debug("ALSA: seq: malloc failed for registering client port\n"); return NULL; /* failure, out of memory */ } /* init port data */ @@ -159,21 +155,20 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, port_subs_info_init(&new_port->c_dest); num = port >= 0 ? port : 0; - down(&client->ports_mutex); + mutex_lock(&client->ports_mutex); write_lock_irqsave(&client->ports_lock, flags); - list_for_each(l, &client->ports_list_head) { - struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); + list_for_each_entry(p, &client->ports_list_head, list) { if (p->addr.port > num) break; if (port < 0) /* auto-probe mode */ num = p->addr.port + 1; } /* insert the new port */ - list_add_tail(&new_port->list, l); + list_add_tail(&new_port->list, &p->list); client->num_ports++; new_port->addr.port = num; /* store the port number in the port */ write_unlock_irqrestore(&client->ports_lock, flags); - up(&client->ports_mutex); + mutex_unlock(&client->ports_mutex); sprintf(new_port->name, "port-%d", num); return new_port; @@ -221,7 +216,6 @@ static void clear_subscriber_list(struct snd_seq_client *client, { struct list_head *p, *n; - down_write(&grp->list_mutex); list_for_each_safe(p, n, &grp->list_head) { struct snd_seq_subscribers *subs; struct snd_seq_client *c; @@ -252,14 +246,13 @@ static void clear_subscriber_list(struct snd_seq_client *client, list_del(&subs->dest_list); else list_del(&subs->src_list); + up_write(&agrp->list_mutex); unsubscribe_port(c, aport, agrp, &subs->info, 1); kfree(subs); - up_write(&agrp->list_mutex); snd_seq_port_unlock(aport); snd_seq_client_unlock(c); } } - up_write(&grp->list_mutex); } /* delete port data */ @@ -277,8 +270,8 @@ static int port_delete(struct snd_seq_client *client, if (port->private_free) port->private_free(port->private_data); - snd_assert(port->c_src.count == 0,); - snd_assert(port->c_dest.count == 0,); + snd_BUG_ON(port->c_src.count != 0); + snd_BUG_ON(port->c_dest.count != 0); kfree(port); return 0; @@ -289,23 +282,21 @@ static int port_delete(struct snd_seq_client *client, int snd_seq_delete_port(struct snd_seq_client *client, int port) { unsigned long flags; - struct list_head *l; - struct snd_seq_client_port *found = NULL; + struct snd_seq_client_port *found = NULL, *p; - down(&client->ports_mutex); + mutex_lock(&client->ports_mutex); write_lock_irqsave(&client->ports_lock, flags); - list_for_each(l, &client->ports_list_head) { - struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); + list_for_each_entry(p, &client->ports_list_head, list) { if (p->addr.port == port) { /* ok found. delete from the list at first */ - list_del(l); + list_del(&p->list); client->num_ports--; found = p; break; } } write_unlock_irqrestore(&client->ports_lock, flags); - up(&client->ports_mutex); + mutex_unlock(&client->ports_mutex); if (found) return port_delete(client, found); else @@ -316,18 +307,17 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port) int snd_seq_delete_all_ports(struct snd_seq_client *client) { unsigned long flags; - struct list_head deleted_list, *p, *n; + struct list_head deleted_list; + struct snd_seq_client_port *port, *tmp; /* move the port list to deleted_list, and * clear the port list in the client data. */ - down(&client->ports_mutex); + mutex_lock(&client->ports_mutex); write_lock_irqsave(&client->ports_lock, flags); if (! list_empty(&client->ports_list_head)) { - __list_add(&deleted_list, - client->ports_list_head.prev, - client->ports_list_head.next); - INIT_LIST_HEAD(&client->ports_list_head); + list_add(&deleted_list, &client->ports_list_head); + list_del_init(&client->ports_list_head); } else { INIT_LIST_HEAD(&deleted_list); } @@ -335,13 +325,12 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client) write_unlock_irqrestore(&client->ports_lock, flags); /* remove each port in deleted_list */ - list_for_each_safe(p, n, &deleted_list) { - struct snd_seq_client_port *port = list_entry(p, struct snd_seq_client_port, list); - list_del(p); + list_for_each_entry_safe(port, tmp, &deleted_list, list) { + list_del(&port->list); snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port); port_delete(client, port); } - up(&client->ports_mutex); + mutex_unlock(&client->ports_mutex); return 0; } @@ -349,7 +338,8 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client) int snd_seq_set_port_info(struct snd_seq_client_port * port, struct snd_seq_port_info * info) { - snd_assert(port && info, return -EINVAL); + if (snd_BUG_ON(!port || !info)) + return -EINVAL; /* set port name */ if (info->name[0]) @@ -378,7 +368,8 @@ int snd_seq_set_port_info(struct snd_seq_client_port * port, int snd_seq_get_port_info(struct snd_seq_client_port * port, struct snd_seq_port_info * info) { - snd_assert(port && info, return -EINVAL); + if (snd_BUG_ON(!port || !info)) + return -EINVAL; /* get port name */ strlcpy(info->name, port->name, sizeof(info->name)); @@ -422,7 +413,7 @@ int snd_seq_get_port_info(struct snd_seq_client_port * port, * initialization or termination of devices (see seq_midi.c). * * If callback_all option is set, the callback function is invoked - * at each connnection/disconnection. + * at each connection/disconnection. */ static int subscribe_port(struct snd_seq_client *client, @@ -504,8 +495,7 @@ int snd_seq_port_connect(struct snd_seq_client *connector, { struct snd_seq_port_subs_info *src = &src_port->c_src; struct snd_seq_port_subs_info *dest = &dest_port->c_dest; - struct snd_seq_subscribers *subs; - struct list_head *p; + struct snd_seq_subscribers *subs, *s; int err, src_called = 0; unsigned long flags; int exclusive; @@ -518,7 +508,7 @@ int snd_seq_port_connect(struct snd_seq_client *connector, atomic_set(&subs->ref_count, 2); down_write(&src->list_mutex); - down_write(&dest->list_mutex); + down_write_nested(&dest->list_mutex, SINGLE_DEPTH_NESTING); exclusive = info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE ? 1 : 0; err = -EBUSY; @@ -529,13 +519,11 @@ int snd_seq_port_connect(struct snd_seq_client *connector, if (src->exclusive || dest->exclusive) goto __error; /* check whether already exists */ - list_for_each(p, &src->list_head) { - struct snd_seq_subscribers *s = list_entry(p, struct snd_seq_subscribers, src_list); + list_for_each_entry(s, &src->list_head, src_list) { if (match_subs_info(info, &s->info)) goto __error; } - list_for_each(p, &dest->list_head) { - struct snd_seq_subscribers *s = list_entry(p, struct snd_seq_subscribers, dest_list); + list_for_each_entry(s, &dest->list_head, dest_list) { if (match_subs_info(info, &s->info)) goto __error; } @@ -586,16 +574,14 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector, struct snd_seq_port_subs_info *src = &src_port->c_src; struct snd_seq_port_subs_info *dest = &dest_port->c_dest; struct snd_seq_subscribers *subs; - struct list_head *p; int err = -ENOENT; unsigned long flags; down_write(&src->list_mutex); - down_write(&dest->list_mutex); + down_write_nested(&dest->list_mutex, SINGLE_DEPTH_NESTING); /* look for the connection */ - list_for_each(p, &src->list_head) { - subs = list_entry(p, struct snd_seq_subscribers, src_list); + list_for_each_entry(subs, &src->list_head, src_list) { if (match_subs_info(info, &subs->info)) { write_lock_irqsave(&src->list_lock, flags); // write_lock(&dest->list_lock); // no lock yet @@ -624,12 +610,10 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector, struct snd_seq_subscribers *snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp, struct snd_seq_addr *dest_addr) { - struct list_head *p; struct snd_seq_subscribers *s, *found = NULL; down_read(&src_grp->list_mutex); - list_for_each(p, &src_grp->list_head) { - s = list_entry(p, struct snd_seq_subscribers, src_list); + list_for_each_entry(s, &src_grp->list_head, src_list) { if (addr_match(dest_addr, &s->info.dest)) { found = s; break; @@ -677,6 +661,7 @@ int snd_seq_event_port_attach(int client, return ret; } +EXPORT_SYMBOL(snd_seq_event_port_attach); /* * Detach the driver from a port. @@ -696,3 +681,5 @@ int snd_seq_event_port_detach(int client, int port) return err; } + +EXPORT_SYMBOL(snd_seq_event_port_detach); diff --git a/sound/core/seq/seq_prioq.c b/sound/core/seq/seq_prioq.c index 074418617ee..021b02bc933 100644 --- a/sound/core/seq/seq_prioq.c +++ b/sound/core/seq/seq_prioq.c @@ -19,7 +19,6 @@ * */ -#include <sound/driver.h> #include <linux/time.h> #include <linux/slab.h> #include <sound/core.h> @@ -61,7 +60,7 @@ struct snd_seq_prioq *snd_seq_prioq_new(void) f = kzalloc(sizeof(*f), GFP_KERNEL); if (f == NULL) { - snd_printd("oops: malloc failed for snd_seq_prioq_new()\n"); + pr_debug("ALSA: seq: malloc failed for snd_seq_prioq_new()\n"); return NULL; } @@ -80,7 +79,7 @@ void snd_seq_prioq_delete(struct snd_seq_prioq **fifo) *fifo = NULL; if (f == NULL) { - snd_printd("oops: snd_seq_prioq_delete() called with NULL prioq\n"); + pr_debug("ALSA: seq: snd_seq_prioq_delete() called with NULL prioq\n"); return; } @@ -154,8 +153,8 @@ int snd_seq_prioq_cell_in(struct snd_seq_prioq * f, int count; int prior; - snd_assert(f, return -EINVAL); - snd_assert(cell, return -EINVAL); + if (snd_BUG_ON(!f || !cell)) + return -EINVAL; /* check flags */ prior = (cell->event.flags & SNDRV_SEQ_PRIORITY_MASK); @@ -198,7 +197,7 @@ int snd_seq_prioq_cell_in(struct snd_seq_prioq * f, cur = cur->next; if (! --count) { spin_unlock_irqrestore(&f->lock, flags); - snd_printk(KERN_ERR "cannot find a pointer.. infinite loop?\n"); + pr_err("ALSA: seq: cannot find a pointer.. infinite loop?\n"); return -EINVAL; } } @@ -224,7 +223,7 @@ struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f) unsigned long flags; if (f == NULL) { - snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n"); + pr_debug("ALSA: seq: snd_seq_prioq_cell_in() called with NULL prioq\n"); return NULL; } spin_lock_irqsave(&f->lock, flags); @@ -249,7 +248,7 @@ struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f) int snd_seq_prioq_avail(struct snd_seq_prioq * f) { if (f == NULL) { - snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n"); + pr_debug("ALSA: seq: snd_seq_prioq_cell_in() called with NULL prioq\n"); return 0; } return f->cells; @@ -260,7 +259,7 @@ int snd_seq_prioq_avail(struct snd_seq_prioq * f) struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq * f) { if (f == NULL) { - snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n"); + pr_debug("ALSA: seq: snd_seq_prioq_cell_in() called with NULL prioq\n"); return NULL; } return f->head; @@ -322,7 +321,8 @@ void snd_seq_prioq_leave(struct snd_seq_prioq * f, int client, int timestamp) freeprev = cell; } else { #if 0 - printk("type = %i, source = %i, dest = %i, client = %i\n", + pr_debug("ALSA: seq: type = %i, source = %i, dest = %i, " + "client = %i\n", cell->event.type, cell->event.source.client, cell->event.dest.client, diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index 9cf20f04554..aad4878cee5 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -35,7 +35,6 @@ * - Addition of experimental sync support. */ -#include <sound/driver.h> #include <linux/init.h> #include <linux/slab.h> #include <sound/core.h> @@ -113,13 +112,13 @@ static struct snd_seq_queue *queue_new(int owner, int locked) q = kzalloc(sizeof(*q), GFP_KERNEL); if (q == NULL) { - snd_printd("malloc failed for snd_seq_queue_new()\n"); + pr_debug("ALSA: seq: malloc failed for snd_seq_queue_new()\n"); return NULL; } spin_lock_init(&q->owner_lock); spin_lock_init(&q->check_lock); - init_MUTEX(&q->timer_mutex); + mutex_init(&q->timer_mutex); snd_use_lock_init(&q->use_lock); q->queue = -1; @@ -316,7 +315,8 @@ int snd_seq_enqueue_event(struct snd_seq_event_cell *cell, int atomic, int hop) int dest, err; struct snd_seq_queue *q; - snd_assert(cell != NULL, return -EINVAL); + if (snd_BUG_ON(!cell)) + return -EINVAL; dest = cell->event.queue; /* destination queue */ q = queueptr(dest); if (q == NULL) @@ -467,13 +467,11 @@ int snd_seq_queue_timer_open(int queueid) int snd_seq_queue_timer_close(int queueid) { struct snd_seq_queue *queue; - struct snd_seq_timer *tmr; int result = 0; queue = queueptr(queueid); if (queue == NULL) return -EINVAL; - tmr = queue->timer; snd_seq_timer_close(queue); queuefree(queue); return result; @@ -516,7 +514,7 @@ int snd_seq_queue_use(int queueid, int client, int use) queue = queueptr(queueid); if (queue == NULL) return -EINVAL; - down(&queue->timer_mutex); + mutex_lock(&queue->timer_mutex); if (use) { if (!test_and_set_bit(client, queue->clients_bitmap)) queue->clients++; @@ -531,7 +529,7 @@ int snd_seq_queue_use(int queueid, int client, int use) } else { snd_seq_timer_close(queue); } - up(&queue->timer_mutex); + mutex_unlock(&queue->timer_mutex); queuefree(queue); return 0; } @@ -735,7 +733,8 @@ int snd_seq_control_queue(struct snd_seq_event *ev, int atomic, int hop) { struct snd_seq_queue *q; - snd_assert(ev != NULL, return -EINVAL); + if (snd_BUG_ON(!ev)) + return -EINVAL; q = queueptr(ev->data.queue.queue); if (q == NULL) diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h index 88843859938..30c8111477f 100644 --- a/sound/core/seq/seq_queue.h +++ b/sound/core/seq/seq_queue.h @@ -54,7 +54,7 @@ struct snd_seq_queue { /* clients which uses this queue (bitmap) */ DECLARE_BITMAP(clients_bitmap, SNDRV_SEQ_MAX_CLIENTS); unsigned int clients; /* users of this queue */ - struct semaphore timer_mutex; + struct mutex timer_mutex; snd_use_lock_t use_lock; }; diff --git a/sound/core/seq/seq_system.c b/sound/core/seq/seq_system.c index b201b76e941..8ce1d0b40dc 100644 --- a/sound/core/seq/seq_system.c +++ b/sound/core/seq/seq_system.c @@ -19,8 +19,9 @@ * */ -#include <sound/driver.h> #include <linux/init.h> +#include <linux/export.h> +#include <linux/slab.h> #include <sound/core.h> #include "seq_system.h" #include "seq_timer.h" diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c index b4b9a132cb1..e73605393ee 100644 --- a/sound/core/seq/seq_timer.c +++ b/sound/core/seq/seq_timer.c @@ -1,7 +1,7 @@ /* * ALSA sequencer Timer * Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl> - * Jaroslav Kysela <perex@suse.cz> + * Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -20,20 +20,12 @@ * */ -#include <sound/driver.h> #include <sound/core.h> #include <linux/slab.h> #include "seq_timer.h" #include "seq_queue.h" #include "seq_info.h" -extern int seq_default_timer_class; -extern int seq_default_timer_sclass; -extern int seq_default_timer_card; -extern int seq_default_timer_device; -extern int seq_default_timer_subdevice; -extern int seq_default_timer_resolution; - /* allowed sequencer timer frequencies, in Hz */ #define MIN_FREQUENCY 10 #define MAX_FREQUENCY 6250 @@ -41,22 +33,21 @@ extern int seq_default_timer_resolution; #define SKEW_BASE 0x10000 /* 16bit shift */ -static void snd_seq_timer_set_tick_resolution(struct snd_seq_timer_tick *tick, - int tempo, int ppq) +static void snd_seq_timer_set_tick_resolution(struct snd_seq_timer *tmr) { - if (tempo < 1000000) - tick->resolution = (tempo * 1000) / ppq; + if (tmr->tempo < 1000000) + tmr->tick.resolution = (tmr->tempo * 1000) / tmr->ppq; else { /* might overflow.. */ unsigned int s; - s = tempo % ppq; - s = (s * 1000) / ppq; - tick->resolution = (tempo / ppq) * 1000; - tick->resolution += s; + s = tmr->tempo % tmr->ppq; + s = (s * 1000) / tmr->ppq; + tmr->tick.resolution = (tmr->tempo / tmr->ppq) * 1000; + tmr->tick.resolution += s; } - if (tick->resolution <= 0) - tick->resolution = 1; - snd_seq_timer_update_tick(tick, 0); + if (tmr->tick.resolution <= 0) + tmr->tick.resolution = 1; + snd_seq_timer_update_tick(&tmr->tick, 0); } /* create new timer (constructor) */ @@ -66,7 +57,7 @@ struct snd_seq_timer *snd_seq_timer_new(void) tmr = kzalloc(sizeof(*tmr), GFP_KERNEL); if (tmr == NULL) { - snd_printd("malloc failed for snd_seq_timer_new() \n"); + pr_debug("ALSA: seq: malloc failed for snd_seq_timer_new() \n"); return NULL; } spin_lock_init(&tmr->lock); @@ -87,7 +78,7 @@ void snd_seq_timer_delete(struct snd_seq_timer **tmr) *tmr = NULL; if (t == NULL) { - snd_printd("oops: snd_seq_timer_delete() called with NULL timer\n"); + pr_debug("ALSA: seq: snd_seq_timer_delete() called with NULL timer\n"); return; } t->running = 0; @@ -104,7 +95,7 @@ void snd_seq_timer_defaults(struct snd_seq_timer * tmr) /* setup defaults */ tmr->ppq = 96; /* 96 PPQ */ tmr->tempo = 500000; /* 120 BPM */ - snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); + snd_seq_timer_set_tick_resolution(tmr); tmr->running = 0; tmr->type = SNDRV_SEQ_TIMER_ALSA; @@ -181,13 +172,14 @@ int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo) { unsigned long flags; - snd_assert(tmr, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; if (tempo <= 0) return -EINVAL; spin_lock_irqsave(&tmr->lock, flags); if ((unsigned int)tempo != tmr->tempo) { tmr->tempo = tempo; - snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); + snd_seq_timer_set_tick_resolution(tmr); } spin_unlock_irqrestore(&tmr->lock, flags); return 0; @@ -198,7 +190,8 @@ int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq) { unsigned long flags; - snd_assert(tmr, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; if (ppq <= 0) return -EINVAL; spin_lock_irqsave(&tmr->lock, flags); @@ -206,12 +199,12 @@ int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq) /* refuse to change ppq on running timers */ /* because it will upset the song position (ticks) */ spin_unlock_irqrestore(&tmr->lock, flags); - snd_printd("seq: cannot change ppq of a running timer\n"); + pr_debug("ALSA: seq: cannot change ppq of a running timer\n"); return -EBUSY; } tmr->ppq = ppq; - snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); + snd_seq_timer_set_tick_resolution(tmr); spin_unlock_irqrestore(&tmr->lock, flags); return 0; } @@ -222,7 +215,8 @@ int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, { unsigned long flags; - snd_assert(tmr, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; spin_lock_irqsave(&tmr->lock, flags); tmr->tick.cur_tick = position; @@ -237,7 +231,8 @@ int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, { unsigned long flags; - snd_assert(tmr, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; snd_seq_sanity_real_time(&position); spin_lock_irqsave(&tmr->lock, flags); @@ -252,11 +247,12 @@ int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, { unsigned long flags; - snd_assert(tmr, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; /* FIXME */ if (base != SKEW_BASE) { - snd_printd("invalid skew base 0x%x\n", base); + pr_debug("ALSA: seq: invalid skew base 0x%x\n", base); return -EINVAL; } spin_lock_irqsave(&tmr->lock, flags); @@ -273,7 +269,8 @@ int snd_seq_timer_open(struct snd_seq_queue *q) int err; tmr = q->timer; - snd_assert(tmr != NULL, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; if (tmr->timeri) return -EBUSY; sprintf(str, "sequencer queue %i", q->queue); @@ -293,10 +290,10 @@ int snd_seq_timer_open(struct snd_seq_queue *q) tid.device = SNDRV_TIMER_GLOBAL_SYSTEM; err = snd_timer_open(&t, str, &tid, q->queue); } - if (err < 0) { - snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err); - return err; - } + } + if (err < 0) { + pr_err("ALSA: seq fatal error: cannot create timer (%i)\n", err); + return err; } t->callback = snd_seq_timer_interrupt; t->callback_data = q; @@ -310,7 +307,8 @@ int snd_seq_timer_close(struct snd_seq_queue *q) struct snd_seq_timer *tmr; tmr = q->timer; - snd_assert(tmr != NULL, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; if (tmr->timeri) { snd_timer_stop(tmr->timeri); snd_timer_close(tmr->timeri); @@ -336,7 +334,8 @@ static int initialize_timer(struct snd_seq_timer *tmr) unsigned long freq; t = tmr->timeri->timer; - snd_assert(t, return -EINVAL); + if (snd_BUG_ON(!t)) + return -EINVAL; freq = tmr->preferred_resolution; if (!freq) diff --git a/sound/core/seq/seq_timer.h b/sound/core/seq/seq_timer.h index e9ee1543c92..88dfb71805a 100644 --- a/sound/core/seq/seq_timer.h +++ b/sound/core/seq/seq_timer.h @@ -138,4 +138,11 @@ int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, unsigne snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr); snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr); +extern int seq_default_timer_class; +extern int seq_default_timer_sclass; +extern int seq_default_timer_card; +extern int seq_default_timer_device; +extern int seq_default_timer_subdevice; +extern int seq_default_timer_resolution; + #endif diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index 14fd1a608e1..56e0f4cd3f8 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c @@ -35,10 +35,9 @@ * */ -#include <sound/driver.h> #include <linux/init.h> #include <linux/wait.h> -#include <linux/sched.h> +#include <linux/module.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/rawmidi.h> @@ -81,13 +80,11 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, struct snd_seq_event *ev) { struct snd_virmidi *vmidi; - struct list_head *list; unsigned char msg[4]; int len; read_lock(&rdev->filelist_lock); - list_for_each(list, &rdev->filelist) { - vmidi = list_entry(list, struct snd_virmidi, list); + list_for_each_entry(vmidi, &rdev->filelist, list) { if (!vmidi->trigger) continue; if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { @@ -167,7 +164,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, return; /* ignored */ } if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { - if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0) + if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) return; vmidi->event.type = SNDRV_SEQ_EVENT_NONE; } @@ -186,7 +183,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, pbuf += res; count -= res; if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { - if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0) + if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) return; vmidi->event.type = SNDRV_SEQ_EVENT_NONE; } @@ -366,7 +363,7 @@ static int snd_virmidi_dev_attach_seq(struct snd_virmidi_dev *rdev) if (rdev->client >= 0) return 0; - pinfo = kmalloc(sizeof(*pinfo), GFP_KERNEL); + pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL); if (!pinfo) { err = -ENOMEM; goto __error; @@ -383,14 +380,15 @@ static int snd_virmidi_dev_attach_seq(struct snd_virmidi_dev *rdev) rdev->client = client; /* create a port */ - memset(pinfo, 0, sizeof(*pinfo)); pinfo->addr.client = client; sprintf(pinfo->name, "VirMIDI %d-%d", rdev->card->number, rdev->device); /* set all capabilities */ pinfo->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; pinfo->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ; pinfo->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; - pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; + pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC + | SNDRV_SEQ_PORT_TYPE_SOFTWARE + | SNDRV_SEQ_PORT_TYPE_PORT; pinfo->midi_channels = 16; memset(&pcallbacks, 0, sizeof(pcallbacks)); pcallbacks.owner = THIS_MODULE; @@ -448,7 +446,7 @@ static int snd_virmidi_dev_register(struct snd_rawmidi *rmidi) /* should check presence of port more strictly.. */ break; default: - snd_printk(KERN_ERR "seq_mode is not set: %d\n", rdev->seq_mode); + pr_err("ALSA: seq_virmidi: seq_mode is not set: %d\n", rdev->seq_mode); return -EINVAL; } return 0; |
