diff options
Diffstat (limited to 'sound/core/seq')
40 files changed, 484 insertions, 2515 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 92858cf8b6e..16d42679e43 100644 --- a/sound/core/seq/oss/seq_oss.c +++ b/sound/core/seq/oss/seq_oss.c @@ -20,10 +20,8 @@ * 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> @@ -41,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 @@ -166,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); } @@ -176,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); } @@ -185,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); } @@ -200,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); } @@ -208,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, @@ -218,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 @@ -228,22 +225,19 @@ register_device(void) 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"); + &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); mutex_unlock(®ister_mutex); return rc; } - debug_printk(("device registered\n")); mutex_unlock(®ister_mutex); return 0; } @@ -252,11 +246,10 @@ static void unregister_device(void) { mutex_lock(®ister_mutex); - debug_printk(("device unregistered\n")); if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0) - snd_printk(KERN_ERR "error unregister device music\n"); + 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"); + pr_err("ALSA: seq_oss: error unregister device seq\n"); mutex_unlock(®ister_mutex); } 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 2f0d8773ac6..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 */ diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 532a660df51..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> @@ -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) @@ -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); @@ -293,8 +291,8 @@ static void seq_free_client(struct snd_seq_client * client) 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,7 +301,7 @@ 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); } mutex_unlock(®ister_mutex); @@ -321,6 +319,11 @@ 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; + + err = nonseekable_open(inode, file); + if (err < 0) + return err; if (mutex_lock_interruptible(®ister_mutex)) return -ERESTARTSYS; @@ -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) { @@ -2193,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; } @@ -2203,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); } @@ -2224,7 +2240,8 @@ 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; @@ -2273,7 +2290,8 @@ 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) @@ -2296,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 */ @@ -2362,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; @@ -2400,7 +2420,7 @@ 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; } @@ -2473,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; mutex_lock(&client->ports_mutex); - list_for_each(l, &client->ports_list_head) { - struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); + 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), @@ -2491,9 +2510,6 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer, } -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) @@ -2542,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, diff --git a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h index 5e04e20e239..20f0a725ec7 100644 --- a/sound/core/seq/seq_clientmgr.h +++ b/sound/core/seq/seq_clientmgr.h @@ -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 b79d011813c..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> @@ -66,7 +66,7 @@ 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 */ @@ -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; mutex_lock(&ops_mutex); - list_for_each(head, &opslist) { - struct ops_list *ops = list_entry(head, struct ops_list, list); + 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" : ""), @@ -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,12 +150,8 @@ void snd_seq_device_load_drivers(void) if (snd_seq_in_init) return; - if (! current->fs->root) - return; - mutex_lock(&ops_mutex); - list_for_each(head, &opslist) { - struct ops_list *ops = list_entry(head, struct ops_list, list); + list_for_each_entry(ops, &opslist, list) { if (! (ops->driver & DRIVER_LOADED) && ! (ops->driver & DRIVER_REQUESTED)) { ops->used++; @@ -173,7 +168,7 @@ void snd_seq_device_load_drivers(void) /* * 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) @@ -193,7 +188,8 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, 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) @@ -238,7 +234,8 @@ 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) @@ -314,8 +311,8 @@ static int snd_seq_device_dev_disconnect(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) @@ -328,7 +325,7 @@ 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; @@ -341,8 +338,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, 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); } mutex_unlock(&ops->reg_mutex); @@ -394,15 +390,15 @@ 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; @@ -411,14 +407,13 @@ int snd_seq_device_unregister_driver(char *id) /* close and release all devices associated with this driver */ 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); mutex_unlock(&ops->reg_mutex); @@ -464,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; } @@ -472,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); } @@ -491,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; } @@ -500,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); } @@ -512,11 +507,10 @@ 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; mutex_lock(&ops_mutex); - list_for_each(head, &opslist) { - struct ops_list *ops = list_entry(head, struct ops_list, list); + list_for_each_entry(ops, &opslist, list) { if (strcmp(ops->id, id) == 0) { ops->used++; mutex_unlock(&ops_mutex); @@ -565,7 +559,7 @@ static void __exit alsa_seq_device_exit(void) 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) @@ -575,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 e55488d1237..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; +static bool duplex; module_param(ports, int, 0444); MODULE_PARM_DESC(ports, "number of ports to be created"); @@ -199,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 8a7fe5cca1c..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" diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c deleted file mode 100644 index f30d171b6d9..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 { - mutex_lock(&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 { - mutex_unlock(&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); - mutex_init(&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 1a34941d421..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); diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index 4bffe509f71..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) @@ -151,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; } @@ -188,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); @@ -234,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; } @@ -342,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; } @@ -379,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; } @@ -415,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); @@ -427,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); @@ -460,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 63e91431a29..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; @@ -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 1daa5b069c7..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,12 +26,11 @@ 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 <linux/module.h> #include <linux/mutex.h> #include <sound/core.h> #include <sound/rawmidi.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; @@ -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); } @@ -286,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; @@ -359,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); } 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 8c64b58ff77..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 */ @@ -161,15 +157,14 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, num = port >= 0 ? port : 0; 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); @@ -251,9 +246,9 @@ 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); } @@ -275,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; @@ -287,16 +282,14 @@ 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; 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; @@ -314,7 +307,8 @@ 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. @@ -331,9 +325,8 @@ 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); } @@ -345,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]) @@ -374,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)); @@ -418,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, @@ -500,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; @@ -525,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; } @@ -582,7 +574,6 @@ 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; @@ -590,8 +581,7 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector, 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 @@ -620,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; 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 9b87bb0c7f3..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,7 +112,7 @@ 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; } @@ -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; @@ -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_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 0cfa06c6b81..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) { @@ -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,7 +380,6 @@ 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 */ @@ -450,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; |
