diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-02-19 08:30:29 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-02-02 08:21:21 -0500 |
commit | 23c18d4bfd73ee24070849faf98b3ab01263a3c4 (patch) | |
tree | 944e0e24bd847fdbbddd8baf5ab0976c0fdcfa81 | |
parent | 92b7952da8279189aad352efbf9f2e7001de9524 (diff) |
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>
-rw-r--r-- | include/sound/control.h | 11 | ||||
-rw-r--r-- | sound/core/control.c | 27 | ||||
-rw-r--r-- | sound/core/pcm.c | 15 | ||||
-rw-r--r-- | sound/core/rawmidi.c | 14 |
4 files changed, 38 insertions, 29 deletions
diff --git a/include/sound/control.h b/include/sound/control.h index 042613938a1d..75f3054023f7 100644 --- a/include/sound/control.h +++ b/include/sound/control.h | |||
@@ -93,12 +93,17 @@ struct snd_kctl_event { | |||
93 | 93 | ||
94 | struct pid; | 94 | struct pid; |
95 | 95 | ||
96 | enum { | ||
97 | SND_CTL_SUBDEV_PCM, | ||
98 | SND_CTL_SUBDEV_RAWMIDI, | ||
99 | SND_CTL_SUBDEV_ITEMS, | ||
100 | }; | ||
101 | |||
96 | struct snd_ctl_file { | 102 | struct snd_ctl_file { |
97 | struct list_head list; /* list of all control files */ | 103 | struct list_head list; /* list of all control files */ |
98 | struct snd_card *card; | 104 | struct snd_card *card; |
99 | struct pid *pid; | 105 | struct pid *pid; |
100 | int prefer_pcm_subdevice; | 106 | int preferred_subdevice[SND_CTL_SUBDEV_ITEMS]; |
101 | int prefer_rawmidi_subdevice; | ||
102 | wait_queue_head_t change_sleep; | 107 | wait_queue_head_t change_sleep; |
103 | spinlock_t read_lock; | 108 | spinlock_t read_lock; |
104 | struct fasync_struct *fasync; | 109 | struct fasync_struct *fasync; |
@@ -138,6 +143,8 @@ int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn); | |||
138 | #define snd_ctl_unregister_ioctl_compat(fcn) | 143 | #define snd_ctl_unregister_ioctl_compat(fcn) |
139 | #endif | 144 | #endif |
140 | 145 | ||
146 | int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type); | ||
147 | |||
141 | static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id) | 148 | static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id) |
142 | { | 149 | { |
143 | return id->numid - kctl->id.numid; | 150 | return id->numid - kctl->id.numid; |
diff --git a/sound/core/control.c b/sound/core/control.c index bb96a467e88d..cd246a0bcd55 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -50,7 +50,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file) | |||
50 | unsigned long flags; | 50 | unsigned long flags; |
51 | struct snd_card *card; | 51 | struct snd_card *card; |
52 | struct snd_ctl_file *ctl; | 52 | struct snd_ctl_file *ctl; |
53 | int err; | 53 | int i, err; |
54 | 54 | ||
55 | err = nonseekable_open(inode, file); | 55 | err = nonseekable_open(inode, file); |
56 | if (err < 0) | 56 | if (err < 0) |
@@ -79,8 +79,8 @@ static int snd_ctl_open(struct inode *inode, struct file *file) | |||
79 | init_waitqueue_head(&ctl->change_sleep); | 79 | init_waitqueue_head(&ctl->change_sleep); |
80 | spin_lock_init(&ctl->read_lock); | 80 | spin_lock_init(&ctl->read_lock); |
81 | ctl->card = card; | 81 | ctl->card = card; |
82 | ctl->prefer_pcm_subdevice = -1; | 82 | for (i = 0; i < SND_CTL_SUBDEV_ITEMS; i++) |
83 | ctl->prefer_rawmidi_subdevice = -1; | 83 | ctl->preferred_subdevice[i] = -1; |
84 | ctl->pid = get_pid(task_pid(current)); | 84 | ctl->pid = get_pid(task_pid(current)); |
85 | file->private_data = ctl; | 85 | file->private_data = ctl; |
86 | write_lock_irqsave(&card->ctl_files_rwlock, flags); | 86 | write_lock_irqsave(&card->ctl_files_rwlock, flags); |
@@ -1607,6 +1607,27 @@ static int snd_ctl_fasync(int fd, struct file * file, int on) | |||
1607 | return fasync_helper(fd, file, on, &ctl->fasync); | 1607 | return fasync_helper(fd, file, on, &ctl->fasync); |
1608 | } | 1608 | } |
1609 | 1609 | ||
1610 | /* return the preferred subdevice number if already assigned; | ||
1611 | * otherwise return -1 | ||
1612 | */ | ||
1613 | int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type) | ||
1614 | { | ||
1615 | struct snd_ctl_file *kctl; | ||
1616 | int subdevice = -1; | ||
1617 | |||
1618 | read_lock(&card->ctl_files_rwlock); | ||
1619 | list_for_each_entry(kctl, &card->ctl_files, list) { | ||
1620 | if (kctl->pid == task_pid(current)) { | ||
1621 | subdevice = kctl->preferred_subdevice[type]; | ||
1622 | if (subdevice != -1) | ||
1623 | break; | ||
1624 | } | ||
1625 | } | ||
1626 | read_unlock(&card->ctl_files_rwlock); | ||
1627 | return subdevice; | ||
1628 | } | ||
1629 | EXPORT_SYMBOL_GPL(snd_ctl_get_preferred_subdevice); | ||
1630 | |||
1610 | /* | 1631 | /* |
1611 | * ioctl32 compat | 1632 | * ioctl32 compat |
1612 | */ | 1633 | */ |
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index dba5180e5b80..1b7c473720fa 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -161,7 +161,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, | |||
161 | 161 | ||
162 | if (get_user(val, (int __user *)arg)) | 162 | if (get_user(val, (int __user *)arg)) |
163 | return -EFAULT; | 163 | return -EFAULT; |
164 | control->prefer_pcm_subdevice = val; | 164 | control->preferred_subdevice[SND_CTL_SUBDEV_PCM] = val; |
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | } | 167 | } |
@@ -901,9 +901,8 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, | |||
901 | struct snd_pcm_str * pstr; | 901 | struct snd_pcm_str * pstr; |
902 | struct snd_pcm_substream *substream; | 902 | struct snd_pcm_substream *substream; |
903 | struct snd_pcm_runtime *runtime; | 903 | struct snd_pcm_runtime *runtime; |
904 | struct snd_ctl_file *kctl; | ||
905 | struct snd_card *card; | 904 | struct snd_card *card; |
906 | int prefer_subdevice = -1; | 905 | int prefer_subdevice; |
907 | size_t size; | 906 | size_t size; |
908 | 907 | ||
909 | if (snd_BUG_ON(!pcm || !rsubstream)) | 908 | if (snd_BUG_ON(!pcm || !rsubstream)) |
@@ -914,15 +913,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, | |||
914 | return -ENODEV; | 913 | return -ENODEV; |
915 | 914 | ||
916 | card = pcm->card; | 915 | card = pcm->card; |
917 | read_lock(&card->ctl_files_rwlock); | 916 | prefer_subdevice = snd_ctl_get_preferred_subdevice(card, SND_CTL_SUBDEV_PCM); |
918 | list_for_each_entry(kctl, &card->ctl_files, list) { | ||
919 | if (kctl->pid == task_pid(current)) { | ||
920 | prefer_subdevice = kctl->prefer_pcm_subdevice; | ||
921 | if (prefer_subdevice != -1) | ||
922 | break; | ||
923 | } | ||
924 | } | ||
925 | read_unlock(&card->ctl_files_rwlock); | ||
926 | 917 | ||
927 | switch (stream) { | 918 | switch (stream) { |
928 | case SNDRV_PCM_STREAM_PLAYBACK: | 919 | case SNDRV_PCM_STREAM_PLAYBACK: |
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 6fc71a4c8a51..be18162c380f 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c | |||
@@ -369,7 +369,6 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) | |||
369 | struct snd_rawmidi *rmidi; | 369 | struct snd_rawmidi *rmidi; |
370 | struct snd_rawmidi_file *rawmidi_file = NULL; | 370 | struct snd_rawmidi_file *rawmidi_file = NULL; |
371 | wait_queue_t wait; | 371 | wait_queue_t wait; |
372 | struct snd_ctl_file *kctl; | ||
373 | 372 | ||
374 | if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) | 373 | if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) |
375 | return -EINVAL; /* invalid combination */ | 374 | return -EINVAL; /* invalid combination */ |
@@ -413,16 +412,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) | |||
413 | init_waitqueue_entry(&wait, current); | 412 | init_waitqueue_entry(&wait, current); |
414 | add_wait_queue(&rmidi->open_wait, &wait); | 413 | add_wait_queue(&rmidi->open_wait, &wait); |
415 | while (1) { | 414 | while (1) { |
416 | subdevice = -1; | 415 | subdevice = snd_ctl_get_preferred_subdevice(card, SND_CTL_SUBDEV_RAWMIDI); |
417 | read_lock(&card->ctl_files_rwlock); | ||
418 | list_for_each_entry(kctl, &card->ctl_files, list) { | ||
419 | if (kctl->pid == task_pid(current)) { | ||
420 | subdevice = kctl->prefer_rawmidi_subdevice; | ||
421 | if (subdevice != -1) | ||
422 | break; | ||
423 | } | ||
424 | } | ||
425 | read_unlock(&card->ctl_files_rwlock); | ||
426 | err = rawmidi_open_priv(rmidi, subdevice, fflags, rawmidi_file); | 416 | err = rawmidi_open_priv(rmidi, subdevice, fflags, rawmidi_file); |
427 | if (err >= 0) | 417 | if (err >= 0) |
428 | break; | 418 | break; |
@@ -862,7 +852,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, | |||
862 | 852 | ||
863 | if (get_user(val, (int __user *)argp)) | 853 | if (get_user(val, (int __user *)argp)) |
864 | return -EFAULT; | 854 | return -EFAULT; |
865 | control->prefer_rawmidi_subdevice = val; | 855 | control->preferred_subdevice[SND_CTL_SUBDEV_RAWMIDI] = val; |
866 | return 0; | 856 | return 0; |
867 | } | 857 | } |
868 | case SNDRV_CTL_IOCTL_RAWMIDI_INFO: | 858 | case SNDRV_CTL_IOCTL_RAWMIDI_INFO: |