diff options
Diffstat (limited to 'sound/core')
| -rw-r--r-- | sound/core/Kconfig | 9 | ||||
| -rw-r--r-- | sound/core/compress_offload.c | 2 | ||||
| -rw-r--r-- | sound/core/control.c | 20 | ||||
| -rw-r--r-- | sound/core/ctljack.c | 2 | ||||
| -rw-r--r-- | sound/core/hwdep.c | 6 | ||||
| -rw-r--r-- | sound/core/init.c | 23 | ||||
| -rw-r--r-- | sound/core/jack.c | 304 | ||||
| -rw-r--r-- | sound/core/oss/mixer_oss.c | 14 | ||||
| -rw-r--r-- | sound/core/oss/rate.c | 4 | ||||
| -rw-r--r-- | sound/core/pcm.c | 29 | ||||
| -rw-r--r-- | sound/core/pcm_dmaengine.c | 2 | ||||
| -rw-r--r-- | sound/core/pcm_local.h | 7 | ||||
| -rw-r--r-- | sound/core/pcm_memory.c | 12 | ||||
| -rw-r--r-- | sound/core/pcm_native.c | 60 | ||||
| -rw-r--r-- | sound/core/rawmidi.c | 2 | ||||
| -rw-r--r-- | sound/core/seq/oss/seq_oss_midi.c | 4 | ||||
| -rw-r--r-- | sound/core/seq/oss/seq_oss_synth.c | 6 | ||||
| -rw-r--r-- | sound/core/seq/seq_clientmgr.c | 2 | ||||
| -rw-r--r-- | sound/core/seq/seq_memory.c | 2 | ||||
| -rw-r--r-- | sound/core/seq/seq_ports.c | 6 | ||||
| -rw-r--r-- | sound/core/sound.c | 15 | ||||
| -rw-r--r-- | sound/core/timer.c | 10 | ||||
| -rw-r--r-- | sound/core/timer_compat.c | 4 | 
23 files changed, 446 insertions, 99 deletions
| diff --git a/sound/core/Kconfig b/sound/core/Kconfig index d4554f376160..a4050f87f230 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -187,6 +187,15 @@ config SND_CTL_VALIDATION  	  from the driver are in the proper ranges or the check of the invalid  	  access at out-of-array areas. +config SND_JACK_INJECTION_DEBUG +	bool "Sound jack injection interface via debugfs" +	depends on SND_JACK && SND_DEBUG && DEBUG_FS +	help +	  This option can be used to enable or disable sound jack +	  software injection. +	  Say Y if you are debugging via jack injection interface. +	  If unsure select "N". +  config SND_VMASTER  	bool diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index debc30fcf5b3..21ce4c056a92 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -1132,7 +1132,7 @@ static void snd_compress_proc_done(struct snd_compr *compr)  static inline void snd_compress_set_id(struct snd_compr *compr, const char *id)  { -	strlcpy(compr->id, id, sizeof(compr->id)); +	strscpy(compr->id, id, sizeof(compr->id));  }  #else  static inline int snd_compress_proc_init(struct snd_compr *compr) diff --git a/sound/core/control.c b/sound/core/control.c index 3b44378b9dec..5165741a8400 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -261,7 +261,7 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,  	kctl->id.device = ncontrol->device;  	kctl->id.subdevice = ncontrol->subdevice;  	if (ncontrol->name) { -		strlcpy(kctl->id.name, ncontrol->name, sizeof(kctl->id.name)); +		strscpy(kctl->id.name, ncontrol->name, sizeof(kctl->id.name));  		if (strcmp(ncontrol->name, kctl->id.name) != 0)  			pr_warn("ALSA: Control name '%s' truncated to '%s'\n",  				ncontrol->name, kctl->id.name); @@ -701,12 +701,12 @@ static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,  		return -ENOMEM;  	down_read(&snd_ioctl_rwsem);  	info->card = card->number; -	strlcpy(info->id, card->id, sizeof(info->id)); -	strlcpy(info->driver, card->driver, sizeof(info->driver)); -	strlcpy(info->name, card->shortname, sizeof(info->name)); -	strlcpy(info->longname, card->longname, sizeof(info->longname)); -	strlcpy(info->mixername, card->mixername, sizeof(info->mixername)); -	strlcpy(info->components, card->components, sizeof(info->components)); +	strscpy(info->id, card->id, sizeof(info->id)); +	strscpy(info->driver, card->driver, sizeof(info->driver)); +	strscpy(info->name, card->shortname, sizeof(info->name)); +	strscpy(info->longname, card->longname, sizeof(info->longname)); +	strscpy(info->mixername, card->mixername, sizeof(info->mixername)); +	strscpy(info->components, card->components, sizeof(info->components));  	up_read(&snd_ioctl_rwsem);  	if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info))) {  		kfree(info); @@ -836,7 +836,7 @@ static void fill_remaining_elem_value(struct snd_ctl_elem_value *control,  {  	size_t offset = value_sizes[info->type] * info->count; -	offset = (offset + sizeof(u32) - 1) / sizeof(u32); +	offset = DIV_ROUND_UP(offset, sizeof(u32));  	memset32((u32 *)control->value.bytes.data + offset, pattern,  		 sizeof(control->value) / sizeof(u32) - offset);  } @@ -928,7 +928,7 @@ static int sanity_check_elem_value(struct snd_card *card,  	/* check whether the remaining area kept untouched */  	offset = value_sizes[info->type] * info->count; -	offset = (offset + sizeof(u32) - 1) / sizeof(u32); +	offset = DIV_ROUND_UP(offset, sizeof(u32));  	p = (u32 *)control->value.bytes.data + offset;  	for (; offset < sizeof(control->value) / sizeof(u32); offset++, p++) {  		if (*p != pattern) { @@ -2137,7 +2137,7 @@ int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels,  	WARN(strlen(names[info->value.enumerated.item]) >= sizeof(info->value.enumerated.name),  	     "ALSA: too long item name '%s'\n",  	     names[info->value.enumerated.item]); -	strlcpy(info->value.enumerated.name, +	strscpy(info->value.enumerated.name,  		names[info->value.enumerated.item],  		sizeof(info->value.enumerated.name));  	return 0; diff --git a/sound/core/ctljack.c b/sound/core/ctljack.c index 9be4e282f2e0..709b1a9c2caa 100644 --- a/sound/core/ctljack.c +++ b/sound/core/ctljack.c @@ -35,7 +35,7 @@ static int get_available_index(struct snd_card *card, const char *name)  	sid.index = 0;  	sid.iface = SNDRV_CTL_ELEM_IFACE_CARD; -	strlcpy(sid.name, name, sizeof(sid.name)); +	strscpy(sid.name, name, sizeof(sid.name));  	while (snd_ctl_find_id(card, &sid)) {  		sid.index++; diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 0c029892880a..264b8ea64bc2 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -177,8 +177,8 @@ static int snd_hwdep_info(struct snd_hwdep *hw,  	memset(&info, 0, sizeof(info));  	info.card = hw->card->number; -	strlcpy(info.id, hw->id, sizeof(info.id));	 -	strlcpy(info.name, hw->name, sizeof(info.name)); +	strscpy(info.id, hw->id, sizeof(info.id)); +	strscpy(info.name, hw->name, sizeof(info.name));  	info.iface = hw->iface;  	if (copy_to_user(_info, &info, sizeof(info)))  		return -EFAULT; @@ -379,7 +379,7 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,  	hwdep->card = card;  	hwdep->device = device;  	if (id) -		strlcpy(hwdep->id, id, sizeof(hwdep->id)); +		strscpy(hwdep->id, id, sizeof(hwdep->id));  	snd_device_initialize(&hwdep->dev, card);  	hwdep->dev.release = release_hwdep_device; diff --git a/sound/core/init.c b/sound/core/init.c index 75aec71c48a8..45f4b01de23f 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -13,7 +13,9 @@  #include <linux/time.h>  #include <linux/ctype.h>  #include <linux/pm.h> +#include <linux/debugfs.h>  #include <linux/completion.h> +#include <linux/interrupt.h>  #include <sound/core.h>  #include <sound/control.h> @@ -161,6 +163,9 @@ int snd_card_new(struct device *parent, int idx, const char *xid,  {  	struct snd_card *card;  	int err; +#ifdef CONFIG_SND_DEBUG +	char name[8]; +#endif  	if (snd_BUG_ON(!card_ret))  		return -EINVAL; @@ -174,7 +179,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid,  	if (extra_size > 0)  		card->private_data = (char *)card + sizeof(struct snd_card);  	if (xid) -		strlcpy(card->id, xid, sizeof(card->id)); +		strscpy(card->id, xid, sizeof(card->id));  	err = 0;  	mutex_lock(&snd_card_mutex);  	if (idx < 0) /* first check the matching module-name slot */ @@ -244,6 +249,12 @@ int snd_card_new(struct device *parent, int idx, const char *xid,  		dev_err(parent, "unable to create card info\n");  		goto __error_ctl;  	} + +#ifdef CONFIG_SND_DEBUG +	sprintf(name, "card%d", idx); +	card->debugfs_root = debugfs_create_dir(name, sound_debugfs_root); +#endif +  	*card_ret = card;  	return 0; @@ -416,6 +427,9 @@ int snd_card_disconnect(struct snd_card *card)  	/* notify all devices that we are disconnected */  	snd_device_disconnect_all(card); +	if (card->sync_irq > 0) +		synchronize_irq(card->sync_irq); +  	snd_info_card_disconnect(card);  	if (card->registered) {  		device_del(&card->card_dev); @@ -477,6 +491,10 @@ static int snd_card_do_free(struct snd_card *card)  		dev_warn(card->dev, "unable to free card info\n");  		/* Not fatal error */  	} +#ifdef CONFIG_SND_DEBUG +	debugfs_remove(card->debugfs_root); +	card->debugfs_root = NULL; +#endif  	if (card->release_completion)  		complete(card->release_completion);  	kfree(card); @@ -526,6 +544,7 @@ int snd_card_free(struct snd_card *card)  		return ret;  	/* wait, until all devices are ready for the free operation */  	wait_for_completion(&released); +  	return 0;  }  EXPORT_SYMBOL(snd_card_free); @@ -623,7 +642,7 @@ static void snd_card_set_id_no_lock(struct snd_card *card, const char *src,  	/* last resort... */  	dev_err(card->dev, "unable to set card id (%s)\n", id);  	if (card->proc_root->name) -		strlcpy(card->id, card->proc_root->name, sizeof(card->id)); +		strscpy(card->id, card->proc_root->name, sizeof(card->id));  }  /** diff --git a/sound/core/jack.c b/sound/core/jack.c index 503c8af79d55..32350c6aba84 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c @@ -8,6 +8,9 @@  #include <linux/input.h>  #include <linux/slab.h>  #include <linux/module.h> +#include <linux/ctype.h> +#include <linux/mm.h> +#include <linux/debugfs.h>  #include <sound/jack.h>  #include <sound/core.h>  #include <sound/control.h> @@ -16,6 +19,11 @@ struct snd_jack_kctl {  	struct snd_kcontrol *kctl;  	struct list_head list;  /* list of controls belong to the same jack */  	unsigned int mask_bits; /* only masked status bits are reported via kctl */ +	struct snd_jack *jack;  /* pointer to struct snd_jack */ +	bool sw_inject_enable;  /* allow to inject plug event via debugfs */ +#ifdef CONFIG_SND_JACK_INJECTION_DEBUG +	struct dentry *jack_debugfs_root; /* jack_kctl debugfs root */ +#endif  };  #ifdef CONFIG_SND_JACK_INPUT_DEV @@ -109,12 +117,291 @@ static int snd_jack_dev_register(struct snd_device *device)  }  #endif /* CONFIG_SND_JACK_INPUT_DEV */ +#ifdef CONFIG_SND_JACK_INJECTION_DEBUG +static void snd_jack_inject_report(struct snd_jack_kctl *jack_kctl, int status) +{ +	struct snd_jack *jack; +#ifdef CONFIG_SND_JACK_INPUT_DEV +	int i; +#endif +	if (!jack_kctl) +		return; + +	jack = jack_kctl->jack; + +	if (jack_kctl->sw_inject_enable) +		snd_kctl_jack_report(jack->card, jack_kctl->kctl, +				     status & jack_kctl->mask_bits); + +#ifdef CONFIG_SND_JACK_INPUT_DEV +	if (!jack->input_dev) +		return; + +	for (i = 0; i < ARRAY_SIZE(jack->key); i++) { +		int testbit = ((SND_JACK_BTN_0 >> i) & jack_kctl->mask_bits); + +		if (jack->type & testbit) +			input_report_key(jack->input_dev, jack->key[i], +					 status & testbit); +	} + +	for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) { +		int testbit = ((1 << i) & jack_kctl->mask_bits); + +		if (jack->type & testbit) +			input_report_switch(jack->input_dev, +					    jack_switch_types[i], +					    status & testbit); +	} + +	input_sync(jack->input_dev); +#endif /* CONFIG_SND_JACK_INPUT_DEV */ +} + +static ssize_t sw_inject_enable_read(struct file *file, +				     char __user *to, size_t count, loff_t *ppos) +{ +	struct snd_jack_kctl *jack_kctl = file->private_data; +	int len, ret; +	char buf[128]; + +	len = scnprintf(buf, sizeof(buf), "%s: %s\t\t%s: %i\n", "Jack", jack_kctl->kctl->id.name, +			"Inject Enabled", jack_kctl->sw_inject_enable); +	ret = simple_read_from_buffer(to, count, ppos, buf, len); + +	return ret; +} + +static ssize_t sw_inject_enable_write(struct file *file, +				      const char __user *from, size_t count, loff_t *ppos) +{ +	struct snd_jack_kctl *jack_kctl = file->private_data; +	int ret, err; +	unsigned long enable; +	char buf[8] = { 0 }; + +	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, from, count); +	err = kstrtoul(buf, 0, &enable); +	if (err) +		return err; + +	if (jack_kctl->sw_inject_enable == (!!enable)) +		return ret; + +	jack_kctl->sw_inject_enable = !!enable; + +	if (!jack_kctl->sw_inject_enable) +		snd_jack_report(jack_kctl->jack, jack_kctl->jack->hw_status_cache); + +	return ret; +} + +static ssize_t jackin_inject_write(struct file *file, +				   const char __user *from, size_t count, loff_t *ppos) +{ +	struct snd_jack_kctl *jack_kctl = file->private_data; +	int ret, err; +	unsigned long enable; +	char buf[8] = { 0 }; + +	if (!jack_kctl->sw_inject_enable) +		return -EINVAL; + +	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, from, count); +	err = kstrtoul(buf, 0, &enable); +	if (err) +		return err; + +	snd_jack_inject_report(jack_kctl, !!enable ? jack_kctl->mask_bits : 0); + +	return ret; +} + +static ssize_t jack_kctl_id_read(struct file *file, +				 char __user *to, size_t count, loff_t *ppos) +{ +	struct snd_jack_kctl *jack_kctl = file->private_data; +	char buf[64]; +	int len, ret; + +	len = scnprintf(buf, sizeof(buf), "%s\n", jack_kctl->kctl->id.name); +	ret = simple_read_from_buffer(to, count, ppos, buf, len); + +	return ret; +} + +/* the bit definition is aligned with snd_jack_types in jack.h */ +static const char * const jack_events_name[] = { +	"HEADPHONE(0x0001)", "MICROPHONE(0x0002)", "LINEOUT(0x0004)", +	"MECHANICAL(0x0008)", "VIDEOOUT(0x0010)", "LINEIN(0x0020)", +	"", "", "", "BTN_5(0x0200)", "BTN_4(0x0400)", "BTN_3(0x0800)", +	"BTN_2(0x1000)", "BTN_1(0x2000)", "BTN_0(0x4000)", "", +}; + +/* the recommended buffer size is 256 */ +static int parse_mask_bits(unsigned int mask_bits, char *buf, size_t buf_size) +{ +	int i; + +	scnprintf(buf, buf_size, "0x%04x", mask_bits); + +	for (i = 0; i < ARRAY_SIZE(jack_events_name); i++) +		if (mask_bits & (1 << i)) { +			strlcat(buf, " ", buf_size); +			strlcat(buf, jack_events_name[i], buf_size); +		} +	strlcat(buf, "\n", buf_size); + +	return strlen(buf); +} + +static ssize_t jack_kctl_mask_bits_read(struct file *file, +					char __user *to, size_t count, loff_t *ppos) +{ +	struct snd_jack_kctl *jack_kctl = file->private_data; +	char buf[256]; +	int len, ret; + +	len = parse_mask_bits(jack_kctl->mask_bits, buf, sizeof(buf)); +	ret = simple_read_from_buffer(to, count, ppos, buf, len); + +	return ret; +} + +static ssize_t jack_kctl_status_read(struct file *file, +				     char __user *to, size_t count, loff_t *ppos) +{ +	struct snd_jack_kctl *jack_kctl = file->private_data; +	char buf[16]; +	int len, ret; + +	len = scnprintf(buf, sizeof(buf), "%s\n", jack_kctl->kctl->private_value ? +			"Plugged" : "Unplugged"); +	ret = simple_read_from_buffer(to, count, ppos, buf, len); + +	return ret; +} + +#ifdef CONFIG_SND_JACK_INPUT_DEV +static ssize_t jack_type_read(struct file *file, +			      char __user *to, size_t count, loff_t *ppos) +{ +	struct snd_jack_kctl *jack_kctl = file->private_data; +	char buf[256]; +	int len, ret; + +	len = parse_mask_bits(jack_kctl->jack->type, buf, sizeof(buf)); +	ret = simple_read_from_buffer(to, count, ppos, buf, len); + +	return ret; +} + +static const struct file_operations jack_type_fops = { +	.open = simple_open, +	.read = jack_type_read, +	.llseek = default_llseek, +}; +#endif + +static const struct file_operations sw_inject_enable_fops = { +	.open = simple_open, +	.read = sw_inject_enable_read, +	.write = sw_inject_enable_write, +	.llseek = default_llseek, +}; + +static const struct file_operations jackin_inject_fops = { +	.open = simple_open, +	.write = jackin_inject_write, +	.llseek = default_llseek, +}; + +static const struct file_operations jack_kctl_id_fops = { +	.open = simple_open, +	.read = jack_kctl_id_read, +	.llseek = default_llseek, +}; + +static const struct file_operations jack_kctl_mask_bits_fops = { +	.open = simple_open, +	.read = jack_kctl_mask_bits_read, +	.llseek = default_llseek, +}; + +static const struct file_operations jack_kctl_status_fops = { +	.open = simple_open, +	.read = jack_kctl_status_read, +	.llseek = default_llseek, +}; + +static int snd_jack_debugfs_add_inject_node(struct snd_jack *jack, +					    struct snd_jack_kctl *jack_kctl) +{ +	char *tname; +	int i; + +	/* Don't create injection interface for Phantom jacks */ +	if (strstr(jack_kctl->kctl->id.name, "Phantom")) +		return 0; + +	tname = kstrdup(jack_kctl->kctl->id.name, GFP_KERNEL); +	if (!tname) +		return -ENOMEM; + +	/* replace the chars which are not suitable for folder's name with _ */ +	for (i = 0; tname[i]; i++) +		if (!isalnum(tname[i])) +			tname[i] = '_'; + +	jack_kctl->jack_debugfs_root = debugfs_create_dir(tname, jack->card->debugfs_root); +	kfree(tname); + +	debugfs_create_file("sw_inject_enable", 0644, jack_kctl->jack_debugfs_root, jack_kctl, +			    &sw_inject_enable_fops); + +	debugfs_create_file("jackin_inject", 0200, jack_kctl->jack_debugfs_root, jack_kctl, +			    &jackin_inject_fops); + +	debugfs_create_file("kctl_id", 0444, jack_kctl->jack_debugfs_root, jack_kctl, +			    &jack_kctl_id_fops); + +	debugfs_create_file("mask_bits", 0444, jack_kctl->jack_debugfs_root, jack_kctl, +			    &jack_kctl_mask_bits_fops); + +	debugfs_create_file("status", 0444, jack_kctl->jack_debugfs_root, jack_kctl, +			    &jack_kctl_status_fops); + +#ifdef CONFIG_SND_JACK_INPUT_DEV +	debugfs_create_file("type", 0444, jack_kctl->jack_debugfs_root, jack_kctl, +			    &jack_type_fops); +#endif +	return 0; +} + +static void snd_jack_debugfs_clear_inject_node(struct snd_jack_kctl *jack_kctl) +{ +	debugfs_remove(jack_kctl->jack_debugfs_root); +	jack_kctl->jack_debugfs_root = NULL; +} +#else /* CONFIG_SND_JACK_INJECTION_DEBUG */ +static int snd_jack_debugfs_add_inject_node(struct snd_jack *jack, +					    struct snd_jack_kctl *jack_kctl) +{ +	return 0; +} + +static void snd_jack_debugfs_clear_inject_node(struct snd_jack_kctl *jack_kctl) +{ +} +#endif /* CONFIG_SND_JACK_INJECTION_DEBUG */ +  static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl)  {  	struct snd_jack_kctl *jack_kctl;  	jack_kctl = kctl->private_data;  	if (jack_kctl) { +		snd_jack_debugfs_clear_inject_node(jack_kctl);  		list_del(&jack_kctl->list);  		kfree(jack_kctl);  	} @@ -122,7 +409,9 @@ static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl)  static void snd_jack_kctl_add(struct snd_jack *jack, struct snd_jack_kctl *jack_kctl)  { +	jack_kctl->jack = jack;  	list_add_tail(&jack_kctl->list, &jack->kctl_list); +	snd_jack_debugfs_add_inject_node(jack, jack_kctl);  }  static struct snd_jack_kctl * snd_jack_kctl_new(struct snd_card *card, const char *name, unsigned int mask) @@ -340,6 +629,7 @@ EXPORT_SYMBOL(snd_jack_set_key);  void snd_jack_report(struct snd_jack *jack, int status)  {  	struct snd_jack_kctl *jack_kctl; +	unsigned int mask_bits = 0;  #ifdef CONFIG_SND_JACK_INPUT_DEV  	int i;  #endif @@ -347,16 +637,21 @@ void snd_jack_report(struct snd_jack *jack, int status)  	if (!jack)  		return; +	jack->hw_status_cache = status; +  	list_for_each_entry(jack_kctl, &jack->kctl_list, list) -		snd_kctl_jack_report(jack->card, jack_kctl->kctl, -					    status & jack_kctl->mask_bits); +		if (jack_kctl->sw_inject_enable) +			mask_bits |= jack_kctl->mask_bits; +		else +			snd_kctl_jack_report(jack->card, jack_kctl->kctl, +					     status & jack_kctl->mask_bits);  #ifdef CONFIG_SND_JACK_INPUT_DEV  	if (!jack->input_dev)  		return;  	for (i = 0; i < ARRAY_SIZE(jack->key); i++) { -		int testbit = SND_JACK_BTN_0 >> i; +		int testbit = ((SND_JACK_BTN_0 >> i) & ~mask_bits);  		if (jack->type & testbit)  			input_report_key(jack->input_dev, jack->key[i], @@ -364,7 +659,8 @@ void snd_jack_report(struct snd_jack *jack, int status)  	}  	for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) { -		int testbit = 1 << i; +		int testbit = ((1 << i) & ~mask_bits); +  		if (jack->type & testbit)  			input_report_switch(jack->input_dev,  					    jack_switch_types[i], diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index f702c96a7478..bec928327478 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -87,8 +87,8 @@ static int snd_mixer_oss_info(struct snd_mixer_oss_file *fmixer,  	struct mixer_info info;  	memset(&info, 0, sizeof(info)); -	strlcpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id)); -	strlcpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name)); +	strscpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id)); +	strscpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name));  	info.modify_counter = card->mixer_oss_change_count;  	if (copy_to_user(_info, &info, sizeof(info)))  		return -EFAULT; @@ -103,8 +103,8 @@ static int snd_mixer_oss_info_obsolete(struct snd_mixer_oss_file *fmixer,  	_old_mixer_info info;  	memset(&info, 0, sizeof(info)); -	strlcpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id)); -	strlcpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name)); +	strscpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id)); +	strscpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name));  	if (copy_to_user(_info, &info, sizeof(info)))  		return -EFAULT;  	return 0; @@ -418,7 +418,7 @@ static long snd_mixer_oss_conv(long val, long omin, long omax, long nmin, long n  	if (orange == 0)  		return 0; -	return ((nrange * (val - omin)) + (orange / 2)) / orange + nmin; +	return DIV_ROUND_CLOSEST(nrange * (val - omin), orange) + nmin;  }  /* convert from alsa native to oss values (0-100) */ @@ -499,7 +499,7 @@ static struct snd_kcontrol *snd_mixer_oss_test_id(struct snd_mixer_oss *mixer, c  	memset(&id, 0, sizeof(id));  	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; -	strlcpy(id.name, name, sizeof(id.name)); +	strscpy(id.name, name, sizeof(id.name));  	id.index = index;  	return snd_ctl_find_id(card, &id);  } @@ -1355,7 +1355,7 @@ static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd)  		mixer->oss_dev_alloc = 1;  		mixer->card = card;  		if (*card->mixername) -			strlcpy(mixer->name, card->mixername, sizeof(mixer->name)); +			strscpy(mixer->name, card->mixername, sizeof(mixer->name));  		else  			snprintf(mixer->name, sizeof(mixer->name),  				 "mixer%i", card->number); diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c index d381f4c967c9..98269119347f 100644 --- a/sound/core/oss/rate.c +++ b/sound/core/oss/rate.c @@ -193,7 +193,7 @@ static snd_pcm_sframes_t rate_src_frames(struct snd_pcm_plugin *plugin, snd_pcm_  	if (plugin->src_format.rate < plugin->dst_format.rate) {  		res = (((frames * data->pitch) + (BITS/2)) >> SHIFT);  	} else { -		res = (((frames << SHIFT) + (data->pitch / 2)) / data->pitch);		 +		res = DIV_ROUND_CLOSEST(frames << SHIFT, data->pitch);  	}  	if (data->old_src_frames > 0) {  		snd_pcm_sframes_t frames1 = frames, res1 = data->old_dst_frames; @@ -224,7 +224,7 @@ static snd_pcm_sframes_t rate_dst_frames(struct snd_pcm_plugin *plugin, snd_pcm_  		return 0;  	data = (struct rate_priv *)plugin->extra_data;  	if (plugin->src_format.rate < plugin->dst_format.rate) { -		res = (((frames << SHIFT) + (data->pitch / 2)) / data->pitch); +		res = DIV_ROUND_CLOSEST(frames << SHIFT, data->pitch);  	} else {  		res = (((frames * data->pitch) + (BITS/2)) >> SHIFT);  	} diff --git a/sound/core/pcm.c b/sound/core/pcm.c index be5714f1bb58..b163164a83ec 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -729,7 +729,7 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device,  	init_waitqueue_head(&pcm->open_wait);  	INIT_LIST_HEAD(&pcm->list);  	if (id) -		strlcpy(pcm->id, id, sizeof(pcm->id)); +		strscpy(pcm->id, id, sizeof(pcm->id));  	err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK,  				 playback_count); @@ -1095,22 +1095,23 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)  	mutex_lock(&pcm->open_mutex);  	wake_up(&pcm->open_wait);  	list_del_init(&pcm->list); -	for (cidx = 0; cidx < 2; cidx++) { -		for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) { -			snd_pcm_stream_lock_irq(substream); -			if (substream->runtime) { -				if (snd_pcm_running(substream)) -					snd_pcm_stop(substream, -						     SNDRV_PCM_STATE_DISCONNECTED); -				/* to be sure, set the state unconditionally */ -				substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; -				wake_up(&substream->runtime->sleep); -				wake_up(&substream->runtime->tsleep); -			} -			snd_pcm_stream_unlock_irq(substream); + +	for_each_pcm_substream(pcm, cidx, substream) { +		snd_pcm_stream_lock_irq(substream); +		if (substream->runtime) { +			if (snd_pcm_running(substream)) +				snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); +			/* to be sure, set the state unconditionally */ +			substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; +			wake_up(&substream->runtime->sleep); +			wake_up(&substream->runtime->tsleep);  		} +		snd_pcm_stream_unlock_irq(substream);  	} +	for_each_pcm_substream(pcm, cidx, substream) +		snd_pcm_sync_stop(substream, false); +  	pcm_call_notify(pcm, n_disconnect);  	for (cidx = 0; cidx < 2; cidx++) {  		snd_unregister_device(&pcm->streams[cidx].dev); diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c index 4d0e8fe535a1..1fc2fa077574 100644 --- a/sound/core/pcm_dmaengine.c +++ b/sound/core/pcm_dmaengine.c @@ -125,6 +125,8 @@ void snd_dmaengine_pcm_set_config_from_dai_data(  	}  	slave_config->slave_id = dma_data->slave_id; +	slave_config->peripheral_config = dma_data->peripheral_config; +	slave_config->peripheral_size = dma_data->peripheral_size;  }  EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data); diff --git a/sound/core/pcm_local.h b/sound/core/pcm_local.h index 17a1a5d87098..e3b3558aeab6 100644 --- a/sound/core/pcm_local.h +++ b/sound/core/pcm_local.h @@ -63,6 +63,7 @@ static inline void snd_pcm_timer_done(struct snd_pcm_substream *substream) {}  void __snd_pcm_xrun(struct snd_pcm_substream *substream);  void snd_pcm_group_init(struct snd_pcm_group *group); +void snd_pcm_sync_stop(struct snd_pcm_substream *substream, bool sync_irq);  #ifdef CONFIG_SND_DMA_SGBUF  struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, @@ -71,4 +72,10 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,  #define PCM_RUNTIME_CHECK(sub) snd_BUG_ON(!(sub) || !(sub)->runtime) +/* loop over all PCM substreams */ +#define for_each_pcm_substream(pcm, str, subs) \ +	for ((str) = 0; (str) < 2; (str)++) \ +		for ((subs) = (pcm)->streams[str].substream; (subs); \ +		     (subs) = (subs)->next) +  #endif	/* __SOUND_CORE_PCM_LOCAL_H */ diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index ee6e9c5eec45..289dd1fd8fe7 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -111,9 +111,8 @@ void snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm)  	struct snd_pcm_substream *substream;  	int stream; -	for (stream = 0; stream < 2; stream++) -		for (substream = pcm->streams[stream].substream; substream; substream = substream->next) -			snd_pcm_lib_preallocate_free(substream); +	for_each_pcm_substream(pcm, stream, substream) +		snd_pcm_lib_preallocate_free(substream);  }  EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all); @@ -246,11 +245,8 @@ static void preallocate_pages_for_all(struct snd_pcm *pcm, int type,  	struct snd_pcm_substream *substream;  	int stream; -	for (stream = 0; stream < 2; stream++) -		for (substream = pcm->streams[stream].substream; substream; -		     substream = substream->next) -			preallocate_pages(substream, type, data, size, max, -					  managed); +	for_each_pcm_substream(pcm, stream, substream) +		preallocate_pages(substream, type, data, size, max, managed);  }  /** diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index c4aac703dc22..17a85f4815d5 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -209,13 +209,13 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)  	info->device = pcm->device;  	info->stream = substream->stream;  	info->subdevice = substream->number; -	strlcpy(info->id, pcm->id, sizeof(info->id)); -	strlcpy(info->name, pcm->name, sizeof(info->name)); +	strscpy(info->id, pcm->id, sizeof(info->id)); +	strscpy(info->name, pcm->name, sizeof(info->name));  	info->dev_class = pcm->dev_class;  	info->dev_subclass = pcm->dev_subclass;  	info->subdevices_count = pstr->substream_count;  	info->subdevices_avail = pstr->substream_count - pstr->substream_opened; -	strlcpy(info->subname, substream->name, sizeof(info->subname)); +	strscpy(info->subname, substream->name, sizeof(info->subname));  	return 0;  } @@ -583,13 +583,13 @@ static inline void snd_pcm_timer_notify(struct snd_pcm_substream *substream,  #endif  } -static void snd_pcm_sync_stop(struct snd_pcm_substream *substream) +void snd_pcm_sync_stop(struct snd_pcm_substream *substream, bool sync_irq)  { -	if (substream->runtime->stop_operating) { +	if (substream->runtime && substream->runtime->stop_operating) {  		substream->runtime->stop_operating = false; -		if (substream->ops->sync_stop) +		if (substream->ops && substream->ops->sync_stop)  			substream->ops->sync_stop(substream); -		else if (substream->pcm->card->sync_irq > 0) +		else if (sync_irq && substream->pcm->card->sync_irq > 0)  			synchronize_irq(substream->pcm->card->sync_irq);  	}  } @@ -686,7 +686,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,  		if (atomic_read(&substream->mmap_count))  			return -EBADFD; -	snd_pcm_sync_stop(substream); +	snd_pcm_sync_stop(substream, true);  	params->rmask = ~0U;  	err = snd_pcm_hw_refine(substream, params); @@ -809,7 +809,7 @@ static int do_hw_free(struct snd_pcm_substream *substream)  {  	int result = 0; -	snd_pcm_sync_stop(substream); +	snd_pcm_sync_stop(substream, true);  	if (substream->ops->hw_free)  		result = substream->ops->hw_free(substream);  	if (substream->managed_buffer_alloc) @@ -1421,8 +1421,10 @@ static int snd_pcm_do_stop(struct snd_pcm_substream *substream,  			   snd_pcm_state_t state)  {  	if (substream->runtime->trigger_master == substream && -	    snd_pcm_running(substream)) +	    snd_pcm_running(substream)) {  		substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP); +		substream->runtime->stop_operating = true; +	}  	return 0; /* unconditonally stop all substreams */  } @@ -1435,7 +1437,6 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream,  		runtime->status->state = state;  		snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP);  	} -	runtime->stop_operating = true;  	wake_up(&runtime->sleep);  	wake_up(&runtime->tsleep);  } @@ -1615,6 +1616,7 @@ static int snd_pcm_do_suspend(struct snd_pcm_substream *substream,  	if (! snd_pcm_running(substream))  		return 0;  	substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND); +	runtime->stop_operating = true;  	return 0; /* suspend unconditionally */  } @@ -1672,25 +1674,26 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm)  	if (! pcm)  		return 0; -	for (stream = 0; stream < 2; stream++) { -		for (substream = pcm->streams[stream].substream; -		     substream; substream = substream->next) { -			/* FIXME: the open/close code should lock this as well */ -			if (substream->runtime == NULL) -				continue; +	for_each_pcm_substream(pcm, stream, substream) { +		/* FIXME: the open/close code should lock this as well */ +		if (!substream->runtime) +			continue; -			/* -			 * Skip BE dai link PCM's that are internal and may -			 * not have their substream ops set. -			 */ -			if (!substream->ops) -				continue; +		/* +		 * Skip BE dai link PCM's that are internal and may +		 * not have their substream ops set. +		 */ +		if (!substream->ops) +			continue; -			err = snd_pcm_suspend(substream); -			if (err < 0 && err != -EBUSY) -				return err; -		} +		err = snd_pcm_suspend(substream); +		if (err < 0 && err != -EBUSY) +			return err;  	} + +	for_each_pcm_substream(pcm, stream, substream) +		snd_pcm_sync_stop(substream, false); +  	return 0;  }  EXPORT_SYMBOL(snd_pcm_suspend_all); @@ -1736,7 +1739,6 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream,  	snd_pcm_trigger_tstamp(substream);  	runtime->status->state = runtime->status->suspended_state;  	snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME); -	snd_pcm_sync_stop(substream);  }  static const struct action_ops snd_pcm_action_resume = { @@ -1866,7 +1868,7 @@ static int snd_pcm_do_prepare(struct snd_pcm_substream *substream,  			      snd_pcm_state_t state)  {  	int err; -	snd_pcm_sync_stop(substream); +	snd_pcm_sync_stop(substream, true);  	err = substream->ops->prepare(substream);  	if (err < 0)  		return err; diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 257ad5206240..aca00af93afe 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -1686,7 +1686,7 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device,  	INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams);  	if (id != NULL) -		strlcpy(rmidi->id, id, sizeof(rmidi->id)); +		strscpy(rmidi->id, id, sizeof(rmidi->id));  	snd_device_initialize(&rmidi->dev, card);  	rmidi->dev.release = release_rawmidi_device; diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c index 2ddfe2226651..3f82c196de46 100644 --- a/sound/core/seq/oss/seq_oss_midi.c +++ b/sound/core/seq/oss/seq_oss_midi.c @@ -173,7 +173,7 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo)  	snd_use_lock_init(&mdev->use_lock);  	/* copy and truncate the name of synth device */ -	strlcpy(mdev->name, pinfo->name, sizeof(mdev->name)); +	strscpy(mdev->name, pinfo->name, sizeof(mdev->name));  	/* create MIDI coder */  	if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) { @@ -647,7 +647,7 @@ snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info  	inf->device = dev;  	inf->dev_type = 0; /* FIXME: ?? */  	inf->capabilities = 0; /* FIXME: ?? */ -	strlcpy(inf->name, mdev->name, sizeof(inf->name)); +	strscpy(inf->name, mdev->name, sizeof(inf->name));  	snd_use_lock_free(&mdev->use_lock);  	return 0;  } diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c index 1b8409ec2c97..722f5059b300 100644 --- a/sound/core/seq/oss/seq_oss_synth.c +++ b/sound/core/seq/oss/seq_oss_synth.c @@ -107,7 +107,7 @@ snd_seq_oss_synth_probe(struct device *_dev)  	snd_use_lock_init(&rec->use_lock);  	/* copy and truncate the name of synth device */ -	strlcpy(rec->name, dev->name, sizeof(rec->name)); +	strscpy(rec->name, dev->name, sizeof(rec->name));  	/* registration */  	spin_lock_irqsave(®ister_lock, flags); @@ -617,7 +617,7 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in  		inf->synth_subtype = 0;  		inf->nr_voices = 16;  		inf->device = dev; -		strlcpy(inf->name, minf.name, sizeof(inf->name)); +		strscpy(inf->name, minf.name, sizeof(inf->name));  	} else {  		if ((rec = get_synthdev(dp, dev)) == NULL)  			return -ENXIO; @@ -625,7 +625,7 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in  		inf->synth_subtype = rec->synth_subtype;  		inf->nr_voices = rec->nr_voices;  		inf->device = dev; -		strlcpy(inf->name, rec->name, sizeof(inf->name)); +		strscpy(inf->name, rec->name, sizeof(inf->name));  		snd_use_lock_free(&rec->use_lock);  	}  	return 0; diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index f9f2fea58b32..b6a24fb5e76b 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -1584,7 +1584,7 @@ static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client,  	info->queue = q->queue;  	info->owner = q->owner;  	info->locked = q->locked; -	strlcpy(info->name, q->name, sizeof(info->name)); +	strscpy(info->name, q->name, sizeof(info->name));  	queuefree(q);  	return 0; diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index 65db1a7c77b7..e245bb6ba533 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c @@ -290,7 +290,7 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,  	extlen = 0;  	if (snd_seq_ev_is_variable(event)) {  		extlen = event->data.ext.len & ~SNDRV_SEQ_EXT_MASK; -		ncells = (extlen + sizeof(struct snd_seq_event) - 1) / sizeof(struct snd_seq_event); +		ncells = DIV_ROUND_UP(extlen, sizeof(struct snd_seq_event));  	}  	if (ncells >= pool->total_elements)  		return -ENOMEM; diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index 83be6b982a87..b9c2ce2b8d5a 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c @@ -327,7 +327,7 @@ int snd_seq_set_port_info(struct snd_seq_client_port * port,  	/* set port name */  	if (info->name[0]) -		strlcpy(port->name, info->name, sizeof(port->name)); +		strscpy(port->name, info->name, sizeof(port->name));  	/* set capabilities */  	port->capability = info->capability; @@ -356,7 +356,7 @@ int snd_seq_get_port_info(struct snd_seq_client_port * port,  		return -EINVAL;  	/* get port name */ -	strlcpy(info->name, port->name, sizeof(info->name)); +	strscpy(info->name, port->name, sizeof(info->name));  	/* get capabilities */  	info->capability = port->capability; @@ -654,7 +654,7 @@ int snd_seq_event_port_attach(int client,  	/* Set up the port */  	memset(&portinfo, 0, sizeof(portinfo));  	portinfo.addr.client = client; -	strlcpy(portinfo.name, portname ? portname : "Unnamed port", +	strscpy(portinfo.name, portname ? portname : "Unnamed port",  		sizeof(portinfo.name));  	portinfo.capability = cap; diff --git a/sound/core/sound.c b/sound/core/sound.c index b75f78f2c4b8..af89e51dd44a 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -9,6 +9,7 @@  #include <linux/time.h>  #include <linux/device.h>  #include <linux/module.h> +#include <linux/debugfs.h>  #include <sound/core.h>  #include <sound/minors.h>  #include <sound/info.h> @@ -39,6 +40,11 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);  int snd_ecards_limit;  EXPORT_SYMBOL(snd_ecards_limit); +#ifdef CONFIG_SND_DEBUG +struct dentry *sound_debugfs_root; +EXPORT_SYMBOL_GPL(sound_debugfs_root); +#endif +  static struct snd_minor *snd_minors[SNDRV_OS_MINORS];  static DEFINE_MUTEX(sound_mutex); @@ -337,6 +343,8 @@ static const char *snd_device_type_name(int type)  		return "sequencer";  	case SNDRV_DEVICE_TYPE_TIMER:  		return "timer"; +	case SNDRV_DEVICE_TYPE_COMPRESS: +		return "compress";  	default:  		return "?";  	} @@ -395,6 +403,10 @@ static int __init alsa_sound_init(void)  		unregister_chrdev(major, "alsa");  		return -ENOMEM;  	} + +#ifdef CONFIG_SND_DEBUG +	sound_debugfs_root = debugfs_create_dir("sound", NULL); +#endif  #ifndef MODULE  	pr_info("Advanced Linux Sound Architecture Driver Initialized.\n");  #endif @@ -403,6 +415,9 @@ static int __init alsa_sound_init(void)  static void __exit alsa_sound_exit(void)  { +#ifdef CONFIG_SND_DEBUG +	debugfs_remove(sound_debugfs_root); +#endif  	snd_info_done();  	unregister_chrdev(major, "alsa");  } diff --git a/sound/core/timer.c b/sound/core/timer.c index 765ea66665a8..6898b1ac0d7f 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -959,7 +959,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,  	timer->tmr_device = tid->device;  	timer->tmr_subdevice = tid->subdevice;  	if (id) -		strlcpy(timer->id, id, sizeof(timer->id)); +		strscpy(timer->id, id, sizeof(timer->id));  	timer->sticks = 1;  	INIT_LIST_HEAD(&timer->device_list);  	INIT_LIST_HEAD(&timer->open_list_head); @@ -1659,8 +1659,8 @@ static int snd_timer_user_ginfo(struct file *file,  		ginfo->card = t->card ? t->card->number : -1;  		if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)  			ginfo->flags |= SNDRV_TIMER_FLG_SLAVE; -		strlcpy(ginfo->id, t->id, sizeof(ginfo->id)); -		strlcpy(ginfo->name, t->name, sizeof(ginfo->name)); +		strscpy(ginfo->id, t->id, sizeof(ginfo->id)); +		strscpy(ginfo->name, t->name, sizeof(ginfo->name));  		ginfo->resolution = t->hw.resolution;  		if (t->hw.resolution_min > 0) {  			ginfo->resolution_min = t->hw.resolution_min; @@ -1814,8 +1814,8 @@ static int snd_timer_user_info(struct file *file,  	info->card = t->card ? t->card->number : -1;  	if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)  		info->flags |= SNDRV_TIMER_FLG_SLAVE; -	strlcpy(info->id, t->id, sizeof(info->id)); -	strlcpy(info->name, t->name, sizeof(info->name)); +	strscpy(info->id, t->id, sizeof(info->id)); +	strscpy(info->name, t->name, sizeof(info->name));  	info->resolution = t->hw.resolution;  	if (copy_to_user(_info, info, sizeof(*_info)))  		err = -EFAULT; diff --git a/sound/core/timer_compat.c b/sound/core/timer_compat.c index 0103d16f6f9f..ee973b7b8044 100644 --- a/sound/core/timer_compat.c +++ b/sound/core/timer_compat.c @@ -61,8 +61,8 @@ static int snd_timer_user_info_compat(struct file *file,  	info.card = t->card ? t->card->number : -1;  	if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)  		info.flags |= SNDRV_TIMER_FLG_SLAVE; -	strlcpy(info.id, t->id, sizeof(info.id)); -	strlcpy(info.name, t->name, sizeof(info.name)); +	strscpy(info.id, t->id, sizeof(info.id)); +	strscpy(info.name, t->name, sizeof(info.name));  	info.resolution = t->hw.resolution;  	if (copy_to_user(_info, &info, sizeof(*_info)))  		return -EFAULT; |