ALSA: control: Provide a helper to look for the preferred subdevice
Instead of open-coding the search over the control file loop, provide a helper function for the preferred subdevice assigned to the current process. Reviewed-by: Jaroslav Kysela <perex@perex.cz> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
92b7952da8
commit
23c18d4bfd
4 changed files with 38 additions and 29 deletions
|
@ -93,12 +93,17 @@ struct snd_kctl_event {
|
||||||
|
|
||||||
struct pid;
|
struct pid;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SND_CTL_SUBDEV_PCM,
|
||||||
|
SND_CTL_SUBDEV_RAWMIDI,
|
||||||
|
SND_CTL_SUBDEV_ITEMS,
|
||||||
|
};
|
||||||
|
|
||||||
struct snd_ctl_file {
|
struct snd_ctl_file {
|
||||||
struct list_head list; /* list of all control files */
|
struct list_head list; /* list of all control files */
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
struct pid *pid;
|
struct pid *pid;
|
||||||
int prefer_pcm_subdevice;
|
int preferred_subdevice[SND_CTL_SUBDEV_ITEMS];
|
||||||
int prefer_rawmidi_subdevice;
|
|
||||||
wait_queue_head_t change_sleep;
|
wait_queue_head_t change_sleep;
|
||||||
spinlock_t read_lock;
|
spinlock_t read_lock;
|
||||||
struct fasync_struct *fasync;
|
struct fasync_struct *fasync;
|
||||||
|
@ -138,6 +143,8 @@ int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn);
|
||||||
#define snd_ctl_unregister_ioctl_compat(fcn)
|
#define snd_ctl_unregister_ioctl_compat(fcn)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type);
|
||||||
|
|
||||||
static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
|
static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
|
||||||
{
|
{
|
||||||
return id->numid - kctl->id.numid;
|
return id->numid - kctl->id.numid;
|
||||||
|
|
|
@ -50,7 +50,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
struct snd_ctl_file *ctl;
|
struct snd_ctl_file *ctl;
|
||||||
int err;
|
int i, err;
|
||||||
|
|
||||||
err = nonseekable_open(inode, file);
|
err = nonseekable_open(inode, file);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -79,8 +79,8 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
|
||||||
init_waitqueue_head(&ctl->change_sleep);
|
init_waitqueue_head(&ctl->change_sleep);
|
||||||
spin_lock_init(&ctl->read_lock);
|
spin_lock_init(&ctl->read_lock);
|
||||||
ctl->card = card;
|
ctl->card = card;
|
||||||
ctl->prefer_pcm_subdevice = -1;
|
for (i = 0; i < SND_CTL_SUBDEV_ITEMS; i++)
|
||||||
ctl->prefer_rawmidi_subdevice = -1;
|
ctl->preferred_subdevice[i] = -1;
|
||||||
ctl->pid = get_pid(task_pid(current));
|
ctl->pid = get_pid(task_pid(current));
|
||||||
file->private_data = ctl;
|
file->private_data = ctl;
|
||||||
write_lock_irqsave(&card->ctl_files_rwlock, flags);
|
write_lock_irqsave(&card->ctl_files_rwlock, flags);
|
||||||
|
@ -1607,6 +1607,27 @@ static int snd_ctl_fasync(int fd, struct file * file, int on)
|
||||||
return fasync_helper(fd, file, on, &ctl->fasync);
|
return fasync_helper(fd, file, on, &ctl->fasync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return the preferred subdevice number if already assigned;
|
||||||
|
* otherwise return -1
|
||||||
|
*/
|
||||||
|
int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type)
|
||||||
|
{
|
||||||
|
struct snd_ctl_file *kctl;
|
||||||
|
int subdevice = -1;
|
||||||
|
|
||||||
|
read_lock(&card->ctl_files_rwlock);
|
||||||
|
list_for_each_entry(kctl, &card->ctl_files, list) {
|
||||||
|
if (kctl->pid == task_pid(current)) {
|
||||||
|
subdevice = kctl->preferred_subdevice[type];
|
||||||
|
if (subdevice != -1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
read_unlock(&card->ctl_files_rwlock);
|
||||||
|
return subdevice;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_ctl_get_preferred_subdevice);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ioctl32 compat
|
* ioctl32 compat
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -161,7 +161,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
|
||||||
|
|
||||||
if (get_user(val, (int __user *)arg))
|
if (get_user(val, (int __user *)arg))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
control->prefer_pcm_subdevice = val;
|
control->preferred_subdevice[SND_CTL_SUBDEV_PCM] = val;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -901,9 +901,8 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
|
||||||
struct snd_pcm_str * pstr;
|
struct snd_pcm_str * pstr;
|
||||||
struct snd_pcm_substream *substream;
|
struct snd_pcm_substream *substream;
|
||||||
struct snd_pcm_runtime *runtime;
|
struct snd_pcm_runtime *runtime;
|
||||||
struct snd_ctl_file *kctl;
|
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
int prefer_subdevice = -1;
|
int prefer_subdevice;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
if (snd_BUG_ON(!pcm || !rsubstream))
|
if (snd_BUG_ON(!pcm || !rsubstream))
|
||||||
|
@ -914,15 +913,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
card = pcm->card;
|
card = pcm->card;
|
||||||
read_lock(&card->ctl_files_rwlock);
|
prefer_subdevice = snd_ctl_get_preferred_subdevice(card, SND_CTL_SUBDEV_PCM);
|
||||||
list_for_each_entry(kctl, &card->ctl_files, list) {
|
|
||||||
if (kctl->pid == task_pid(current)) {
|
|
||||||
prefer_subdevice = kctl->prefer_pcm_subdevice;
|
|
||||||
if (prefer_subdevice != -1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
read_unlock(&card->ctl_files_rwlock);
|
|
||||||
|
|
||||||
switch (stream) {
|
switch (stream) {
|
||||||
case SNDRV_PCM_STREAM_PLAYBACK:
|
case SNDRV_PCM_STREAM_PLAYBACK:
|
||||||
|
|
|
@ -369,7 +369,6 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
|
||||||
struct snd_rawmidi *rmidi;
|
struct snd_rawmidi *rmidi;
|
||||||
struct snd_rawmidi_file *rawmidi_file = NULL;
|
struct snd_rawmidi_file *rawmidi_file = NULL;
|
||||||
wait_queue_t wait;
|
wait_queue_t wait;
|
||||||
struct snd_ctl_file *kctl;
|
|
||||||
|
|
||||||
if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
|
if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
|
||||||
return -EINVAL; /* invalid combination */
|
return -EINVAL; /* invalid combination */
|
||||||
|
@ -413,16 +412,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
|
||||||
init_waitqueue_entry(&wait, current);
|
init_waitqueue_entry(&wait, current);
|
||||||
add_wait_queue(&rmidi->open_wait, &wait);
|
add_wait_queue(&rmidi->open_wait, &wait);
|
||||||
while (1) {
|
while (1) {
|
||||||
subdevice = -1;
|
subdevice = snd_ctl_get_preferred_subdevice(card, SND_CTL_SUBDEV_RAWMIDI);
|
||||||
read_lock(&card->ctl_files_rwlock);
|
|
||||||
list_for_each_entry(kctl, &card->ctl_files, list) {
|
|
||||||
if (kctl->pid == task_pid(current)) {
|
|
||||||
subdevice = kctl->prefer_rawmidi_subdevice;
|
|
||||||
if (subdevice != -1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
read_unlock(&card->ctl_files_rwlock);
|
|
||||||
err = rawmidi_open_priv(rmidi, subdevice, fflags, rawmidi_file);
|
err = rawmidi_open_priv(rmidi, subdevice, fflags, rawmidi_file);
|
||||||
if (err >= 0)
|
if (err >= 0)
|
||||||
break;
|
break;
|
||||||
|
@ -862,7 +852,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
|
||||||
|
|
||||||
if (get_user(val, (int __user *)argp))
|
if (get_user(val, (int __user *)argp))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
control->prefer_rawmidi_subdevice = val;
|
control->preferred_subdevice[SND_CTL_SUBDEV_RAWMIDI] = val;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case SNDRV_CTL_IOCTL_RAWMIDI_INFO:
|
case SNDRV_CTL_IOCTL_RAWMIDI_INFO:
|
||||||
|
|
Loading…
Reference in a new issue