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
|
@ -93,12 +93,17 @@ struct snd_kctl_event {
|
|||
|
||||
struct pid;
|
||||
|
||||
enum {
|
||||
SND_CTL_SUBDEV_PCM,
|
||||
SND_CTL_SUBDEV_RAWMIDI,
|
||||
SND_CTL_SUBDEV_ITEMS,
|
||||
};
|
||||
|
||||
struct snd_ctl_file {
|
||||
struct list_head list; /* list of all control files */
|
||||
struct snd_card *card;
|
||||
struct pid *pid;
|
||||
int prefer_pcm_subdevice;
|
||||
int prefer_rawmidi_subdevice;
|
||||
int preferred_subdevice[SND_CTL_SUBDEV_ITEMS];
|
||||
wait_queue_head_t change_sleep;
|
||||
spinlock_t read_lock;
|
||||
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)
|
||||
#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)
|
||||
{
|
||||
return id->numid - kctl->id.numid;
|
||||
|
|
|
@ -50,7 +50,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
|
|||
unsigned long flags;
|
||||
struct snd_card *card;
|
||||
struct snd_ctl_file *ctl;
|
||||
int err;
|
||||
int i, err;
|
||||
|
||||
err = nonseekable_open(inode, file);
|
||||
if (err < 0)
|
||||
|
@ -79,8 +79,8 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
|
|||
init_waitqueue_head(&ctl->change_sleep);
|
||||
spin_lock_init(&ctl->read_lock);
|
||||
ctl->card = card;
|
||||
ctl->prefer_pcm_subdevice = -1;
|
||||
ctl->prefer_rawmidi_subdevice = -1;
|
||||
for (i = 0; i < SND_CTL_SUBDEV_ITEMS; i++)
|
||||
ctl->preferred_subdevice[i] = -1;
|
||||
ctl->pid = get_pid(task_pid(current));
|
||||
file->private_data = ctl;
|
||||
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 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
|
||||
*/
|
||||
|
|
|
@ -161,7 +161,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
|
|||
|
||||
if (get_user(val, (int __user *)arg))
|
||||
return -EFAULT;
|
||||
control->prefer_pcm_subdevice = val;
|
||||
control->preferred_subdevice[SND_CTL_SUBDEV_PCM] = val;
|
||||
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_substream *substream;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
struct snd_ctl_file *kctl;
|
||||
struct snd_card *card;
|
||||
int prefer_subdevice = -1;
|
||||
int prefer_subdevice;
|
||||
size_t size;
|
||||
|
||||
if (snd_BUG_ON(!pcm || !rsubstream))
|
||||
|
@ -914,15 +913,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
|
|||
return -ENODEV;
|
||||
|
||||
card = pcm->card;
|
||||
read_lock(&card->ctl_files_rwlock);
|
||||
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);
|
||||
prefer_subdevice = snd_ctl_get_preferred_subdevice(card, SND_CTL_SUBDEV_PCM);
|
||||
|
||||
switch (stream) {
|
||||
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_file *rawmidi_file = NULL;
|
||||
wait_queue_t wait;
|
||||
struct snd_ctl_file *kctl;
|
||||
|
||||
if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
|
||||
return -EINVAL; /* invalid combination */
|
||||
|
@ -413,16 +412,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
|
|||
init_waitqueue_entry(&wait, current);
|
||||
add_wait_queue(&rmidi->open_wait, &wait);
|
||||
while (1) {
|
||||
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->prefer_rawmidi_subdevice;
|
||||
if (subdevice != -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
read_unlock(&card->ctl_files_rwlock);
|
||||
subdevice = snd_ctl_get_preferred_subdevice(card, SND_CTL_SUBDEV_RAWMIDI);
|
||||
err = rawmidi_open_priv(rmidi, subdevice, fflags, rawmidi_file);
|
||||
if (err >= 0)
|
||||
break;
|
||||
|
@ -862,7 +852,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
|
|||
|
||||
if (get_user(val, (int __user *)argp))
|
||||
return -EFAULT;
|
||||
control->prefer_rawmidi_subdevice = val;
|
||||
control->preferred_subdevice[SND_CTL_SUBDEV_RAWMIDI] = val;
|
||||
return 0;
|
||||
}
|
||||
case SNDRV_CTL_IOCTL_RAWMIDI_INFO:
|
||||
|
|
Loading…
Reference in New Issue