aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-05-20 05:58:57 -0400
committerTakashi Iwai <tiwai@suse.de>2010-05-20 05:58:57 -0400
commit3374cd1abd478f767aaedf2c21d109596ff0fe72 (patch)
tree46b00a571ba5d86373bd9054fdccc5dc6e28e42f /sound/core
parente40152ee1e1c7a63f4777791863215e3faa37a86 (diff)
parent670ff6abd6caff406b217f8a828d6c03656535d8 (diff)
Merge branch 'topic/core-cleanup' into for-linus
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/control.c5
-rw-r--r--sound/core/info.c74
-rw-r--r--sound/core/oss/mixer_oss.c5
-rw-r--r--sound/core/oss/pcm_oss.c5
-rw-r--r--sound/core/pcm_native.c19
-rw-r--r--sound/core/rawmidi.c5
-rw-r--r--sound/core/seq/seq_clientmgr.c6
-rw-r--r--sound/core/sound.c73
-rw-r--r--sound/core/timer.c6
9 files changed, 123 insertions, 75 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index 439ce64f9d82..070aab490191 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -50,6 +50,10 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
50 struct snd_ctl_file *ctl; 50 struct snd_ctl_file *ctl;
51 int err; 51 int err;
52 52
53 err = nonseekable_open(inode, file);
54 if (err < 0)
55 return err;
56
53 card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL); 57 card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL);
54 if (!card) { 58 if (!card) {
55 err = -ENODEV; 59 err = -ENODEV;
@@ -1388,6 +1392,7 @@ static const struct file_operations snd_ctl_f_ops =
1388 .read = snd_ctl_read, 1392 .read = snd_ctl_read,
1389 .open = snd_ctl_open, 1393 .open = snd_ctl_open,
1390 .release = snd_ctl_release, 1394 .release = snd_ctl_release,
1395 .llseek = no_llseek,
1391 .poll = snd_ctl_poll, 1396 .poll = snd_ctl_poll,
1392 .unlocked_ioctl = snd_ctl_ioctl, 1397 .unlocked_ioctl = snd_ctl_ioctl,
1393 .compat_ioctl = snd_ctl_ioctl_compat, 1398 .compat_ioctl = snd_ctl_ioctl_compat,
diff --git a/sound/core/info.c b/sound/core/info.c
index cc4a53d4b7f8..b70564ed8b37 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -164,40 +164,44 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
164{ 164{
165 struct snd_info_private_data *data; 165 struct snd_info_private_data *data;
166 struct snd_info_entry *entry; 166 struct snd_info_entry *entry;
167 loff_t ret; 167 loff_t ret = -EINVAL, size;
168 168
169 data = file->private_data; 169 data = file->private_data;
170 entry = data->entry; 170 entry = data->entry;
171 lock_kernel(); 171 mutex_lock(&entry->access);
172 switch (entry->content) { 172 if (entry->content == SNDRV_INFO_CONTENT_DATA &&
173 case SNDRV_INFO_CONTENT_TEXT: 173 entry->c.ops->llseek) {
174 switch (orig) { 174 offset = entry->c.ops->llseek(entry,
175 case SEEK_SET: 175 data->file_private_data,
176 file->f_pos = offset; 176 file, offset, orig);
177 ret = file->f_pos; 177 goto out;
178 goto out; 178 }
179 case SEEK_CUR: 179 if (entry->content == SNDRV_INFO_CONTENT_DATA)
180 file->f_pos += offset; 180 size = entry->size;
181 ret = file->f_pos; 181 else
182 goto out; 182 size = 0;
183 case SEEK_END: 183 switch (orig) {
184 default: 184 case SEEK_SET:
185 ret = -EINVAL;
186 goto out;
187 }
188 break; 185 break;
189 case SNDRV_INFO_CONTENT_DATA: 186 case SEEK_CUR:
190 if (entry->c.ops->llseek) { 187 offset += file->f_pos;
191 ret = entry->c.ops->llseek(entry, 188 break;
192 data->file_private_data, 189 case SEEK_END:
193 file, offset, orig); 190 if (!size)
194 goto out; 191 goto out;
195 } 192 offset += size;
196 break; 193 break;
197 } 194 default:
198 ret = -ENXIO; 195 goto out;
199out: 196 }
200 unlock_kernel(); 197 if (offset < 0)
198 goto out;
199 if (size && offset > size)
200 offset = size;
201 file->f_pos = offset;
202 ret = offset;
203 out:
204 mutex_unlock(&entry->access);
201 return ret; 205 return ret;
202} 206}
203 207
@@ -232,10 +236,15 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
232 return -EFAULT; 236 return -EFAULT;
233 break; 237 break;
234 case SNDRV_INFO_CONTENT_DATA: 238 case SNDRV_INFO_CONTENT_DATA:
235 if (entry->c.ops->read) 239 if (pos >= entry->size)
240 return 0;
241 if (entry->c.ops->read) {
242 size = entry->size - pos;
243 size = min(count, size);
236 size = entry->c.ops->read(entry, 244 size = entry->c.ops->read(entry,
237 data->file_private_data, 245 data->file_private_data,
238 file, buffer, count, pos); 246 file, buffer, size, pos);
247 }
239 break; 248 break;
240 } 249 }
241 if ((ssize_t) size > 0) 250 if ((ssize_t) size > 0)
@@ -282,10 +291,13 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
282 size = count; 291 size = count;
283 break; 292 break;
284 case SNDRV_INFO_CONTENT_DATA: 293 case SNDRV_INFO_CONTENT_DATA:
285 if (entry->c.ops->write) 294 if (entry->c.ops->write && count > 0) {
295 size_t maxsize = entry->size - pos;
296 count = min(count, maxsize);
286 size = entry->c.ops->write(entry, 297 size = entry->c.ops->write(entry,
287 data->file_private_data, 298 data->file_private_data,
288 file, buffer, count, pos); 299 file, buffer, count, pos);
300 }
289 break; 301 break;
290 } 302 }
291 if ((ssize_t) size > 0) 303 if ((ssize_t) size > 0)
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 54e2eb56e4c2..f50ebf20df96 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -43,6 +43,10 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
43 struct snd_mixer_oss_file *fmixer; 43 struct snd_mixer_oss_file *fmixer;
44 int err; 44 int err;
45 45
46 err = nonseekable_open(inode, file);
47 if (err < 0)
48 return err;
49
46 card = snd_lookup_oss_minor_data(iminor(inode), 50 card = snd_lookup_oss_minor_data(iminor(inode),
47 SNDRV_OSS_DEVICE_TYPE_MIXER); 51 SNDRV_OSS_DEVICE_TYPE_MIXER);
48 if (card == NULL) 52 if (card == NULL)
@@ -397,6 +401,7 @@ static const struct file_operations snd_mixer_oss_f_ops =
397 .owner = THIS_MODULE, 401 .owner = THIS_MODULE,
398 .open = snd_mixer_oss_open, 402 .open = snd_mixer_oss_open,
399 .release = snd_mixer_oss_release, 403 .release = snd_mixer_oss_release,
404 .llseek = no_llseek,
400 .unlocked_ioctl = snd_mixer_oss_ioctl, 405 .unlocked_ioctl = snd_mixer_oss_ioctl,
401 .compat_ioctl = snd_mixer_oss_ioctl_compat, 406 .compat_ioctl = snd_mixer_oss_ioctl_compat,
402}; 407};
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 82d4e3329b3d..5c8c7dff8ede 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -2379,6 +2379,10 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
2379 int nonblock; 2379 int nonblock;
2380 wait_queue_t wait; 2380 wait_queue_t wait;
2381 2381
2382 err = nonseekable_open(inode, file);
2383 if (err < 0)
2384 return err;
2385
2382 pcm = snd_lookup_oss_minor_data(iminor(inode), 2386 pcm = snd_lookup_oss_minor_data(iminor(inode),
2383 SNDRV_OSS_DEVICE_TYPE_PCM); 2387 SNDRV_OSS_DEVICE_TYPE_PCM);
2384 if (pcm == NULL) { 2388 if (pcm == NULL) {
@@ -2977,6 +2981,7 @@ static const struct file_operations snd_pcm_oss_f_reg =
2977 .write = snd_pcm_oss_write, 2981 .write = snd_pcm_oss_write,
2978 .open = snd_pcm_oss_open, 2982 .open = snd_pcm_oss_open,
2979 .release = snd_pcm_oss_release, 2983 .release = snd_pcm_oss_release,
2984 .llseek = no_llseek,
2980 .poll = snd_pcm_oss_poll, 2985 .poll = snd_pcm_oss_poll,
2981 .unlocked_ioctl = snd_pcm_oss_ioctl, 2986 .unlocked_ioctl = snd_pcm_oss_ioctl,
2982 .compat_ioctl = snd_pcm_oss_ioctl_compat, 2987 .compat_ioctl = snd_pcm_oss_ioctl_compat,
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 20b5982c996b..b9517f38073c 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2110,7 +2110,9 @@ static int snd_pcm_open_file(struct file *file,
2110static int snd_pcm_playback_open(struct inode *inode, struct file *file) 2110static int snd_pcm_playback_open(struct inode *inode, struct file *file)
2111{ 2111{
2112 struct snd_pcm *pcm; 2112 struct snd_pcm *pcm;
2113 2113 int err = nonseekable_open(inode, file);
2114 if (err < 0)
2115 return err;
2114 pcm = snd_lookup_minor_data(iminor(inode), 2116 pcm = snd_lookup_minor_data(iminor(inode),
2115 SNDRV_DEVICE_TYPE_PCM_PLAYBACK); 2117 SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
2116 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); 2118 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
@@ -2119,7 +2121,9 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file)
2119static int snd_pcm_capture_open(struct inode *inode, struct file *file) 2121static int snd_pcm_capture_open(struct inode *inode, struct file *file)
2120{ 2122{
2121 struct snd_pcm *pcm; 2123 struct snd_pcm *pcm;
2122 2124 int err = nonseekable_open(inode, file);
2125 if (err < 0)
2126 return err;
2123 pcm = snd_lookup_minor_data(iminor(inode), 2127 pcm = snd_lookup_minor_data(iminor(inode),
2124 SNDRV_DEVICE_TYPE_PCM_CAPTURE); 2128 SNDRV_DEVICE_TYPE_PCM_CAPTURE);
2125 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); 2129 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
@@ -3310,18 +3314,13 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
3310 struct snd_pcm_file * pcm_file; 3314 struct snd_pcm_file * pcm_file;
3311 struct snd_pcm_substream *substream; 3315 struct snd_pcm_substream *substream;
3312 struct snd_pcm_runtime *runtime; 3316 struct snd_pcm_runtime *runtime;
3313 int err = -ENXIO;
3314 3317
3315 lock_kernel();
3316 pcm_file = file->private_data; 3318 pcm_file = file->private_data;
3317 substream = pcm_file->substream; 3319 substream = pcm_file->substream;
3318 if (PCM_RUNTIME_CHECK(substream)) 3320 if (PCM_RUNTIME_CHECK(substream))
3319 goto out; 3321 return -ENXIO;
3320 runtime = substream->runtime; 3322 runtime = substream->runtime;
3321 err = fasync_helper(fd, file, on, &runtime->fasync); 3323 return fasync_helper(fd, file, on, &runtime->fasync);
3322out:
3323 unlock_kernel();
3324 return err;
3325} 3324}
3326 3325
3327/* 3326/*
@@ -3462,6 +3461,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
3462 .aio_write = snd_pcm_aio_write, 3461 .aio_write = snd_pcm_aio_write,
3463 .open = snd_pcm_playback_open, 3462 .open = snd_pcm_playback_open,
3464 .release = snd_pcm_release, 3463 .release = snd_pcm_release,
3464 .llseek = no_llseek,
3465 .poll = snd_pcm_playback_poll, 3465 .poll = snd_pcm_playback_poll,
3466 .unlocked_ioctl = snd_pcm_playback_ioctl, 3466 .unlocked_ioctl = snd_pcm_playback_ioctl,
3467 .compat_ioctl = snd_pcm_ioctl_compat, 3467 .compat_ioctl = snd_pcm_ioctl_compat,
@@ -3475,6 +3475,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
3475 .aio_read = snd_pcm_aio_read, 3475 .aio_read = snd_pcm_aio_read,
3476 .open = snd_pcm_capture_open, 3476 .open = snd_pcm_capture_open,
3477 .release = snd_pcm_release, 3477 .release = snd_pcm_release,
3478 .llseek = no_llseek,
3478 .poll = snd_pcm_capture_poll, 3479 .poll = snd_pcm_capture_poll,
3479 .unlocked_ioctl = snd_pcm_capture_ioctl, 3480 .unlocked_ioctl = snd_pcm_capture_ioctl,
3480 .compat_ioctl = snd_pcm_ioctl_compat, 3481 .compat_ioctl = snd_pcm_ioctl_compat,
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 0f5a194695d9..eb68326c37d4 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -376,6 +376,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
376 if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) 376 if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
377 return -EINVAL; /* invalid combination */ 377 return -EINVAL; /* invalid combination */
378 378
379 err = nonseekable_open(inode, file);
380 if (err < 0)
381 return err;
382
379 if (maj == snd_major) { 383 if (maj == snd_major) {
380 rmidi = snd_lookup_minor_data(iminor(inode), 384 rmidi = snd_lookup_minor_data(iminor(inode),
381 SNDRV_DEVICE_TYPE_RAWMIDI); 385 SNDRV_DEVICE_TYPE_RAWMIDI);
@@ -1391,6 +1395,7 @@ static const struct file_operations snd_rawmidi_f_ops =
1391 .write = snd_rawmidi_write, 1395 .write = snd_rawmidi_write,
1392 .open = snd_rawmidi_open, 1396 .open = snd_rawmidi_open,
1393 .release = snd_rawmidi_release, 1397 .release = snd_rawmidi_release,
1398 .llseek = no_llseek,
1394 .poll = snd_rawmidi_poll, 1399 .poll = snd_rawmidi_poll,
1395 .unlocked_ioctl = snd_rawmidi_ioctl, 1400 .unlocked_ioctl = snd_rawmidi_ioctl,
1396 .compat_ioctl = snd_rawmidi_ioctl_compat, 1401 .compat_ioctl = snd_rawmidi_ioctl_compat,
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 48eca9ff9ee7..99a485f13648 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -318,6 +318,11 @@ static int snd_seq_open(struct inode *inode, struct file *file)
318 int c, mode; /* client id */ 318 int c, mode; /* client id */
319 struct snd_seq_client *client; 319 struct snd_seq_client *client;
320 struct snd_seq_user_client *user; 320 struct snd_seq_user_client *user;
321 int err;
322
323 err = nonseekable_open(inode, file);
324 if (err < 0)
325 return err;
321 326
322 if (mutex_lock_interruptible(&register_mutex)) 327 if (mutex_lock_interruptible(&register_mutex))
323 return -ERESTARTSYS; 328 return -ERESTARTSYS;
@@ -2550,6 +2555,7 @@ static const struct file_operations snd_seq_f_ops =
2550 .write = snd_seq_write, 2555 .write = snd_seq_write,
2551 .open = snd_seq_open, 2556 .open = snd_seq_open,
2552 .release = snd_seq_release, 2557 .release = snd_seq_release,
2558 .llseek = no_llseek,
2553 .poll = snd_seq_poll, 2559 .poll = snd_seq_poll,
2554 .unlocked_ioctl = snd_seq_ioctl, 2560 .unlocked_ioctl = snd_seq_ioctl,
2555 .compat_ioctl = snd_seq_ioctl_compat, 2561 .compat_ioctl = snd_seq_ioctl_compat,
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 563d1967a0ad..ac42af42b787 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -120,7 +120,29 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
120 120
121EXPORT_SYMBOL(snd_lookup_minor_data); 121EXPORT_SYMBOL(snd_lookup_minor_data);
122 122
123static int __snd_open(struct inode *inode, struct file *file) 123#ifdef CONFIG_MODULES
124static struct snd_minor *autoload_device(unsigned int minor)
125{
126 int dev;
127 mutex_unlock(&sound_mutex); /* release lock temporarily */
128 dev = SNDRV_MINOR_DEVICE(minor);
129 if (dev == SNDRV_MINOR_CONTROL) {
130 /* /dev/aloadC? */
131 int card = SNDRV_MINOR_CARD(minor);
132 if (snd_cards[card] == NULL)
133 snd_request_card(card);
134 } else if (dev == SNDRV_MINOR_GLOBAL) {
135 /* /dev/aloadSEQ */
136 snd_request_other(minor);
137 }
138 mutex_lock(&sound_mutex); /* reacuire lock */
139 return snd_minors[minor];
140}
141#else /* !CONFIG_MODULES */
142#define autoload_device(minor) NULL
143#endif /* CONFIG_MODULES */
144
145static int snd_open(struct inode *inode, struct file *file)
124{ 146{
125 unsigned int minor = iminor(inode); 147 unsigned int minor = iminor(inode);
126 struct snd_minor *mptr = NULL; 148 struct snd_minor *mptr = NULL;
@@ -129,55 +151,36 @@ static int __snd_open(struct inode *inode, struct file *file)
129 151
130 if (minor >= ARRAY_SIZE(snd_minors)) 152 if (minor >= ARRAY_SIZE(snd_minors))
131 return -ENODEV; 153 return -ENODEV;
154 mutex_lock(&sound_mutex);
132 mptr = snd_minors[minor]; 155 mptr = snd_minors[minor];
133 if (mptr == NULL) { 156 if (mptr == NULL) {
134#ifdef CONFIG_MODULES 157 mptr = autoload_device(minor);
135 int dev = SNDRV_MINOR_DEVICE(minor); 158 if (!mptr) {
136 if (dev == SNDRV_MINOR_CONTROL) { 159 mutex_unlock(&sound_mutex);
137 /* /dev/aloadC? */
138 int card = SNDRV_MINOR_CARD(minor);
139 if (snd_cards[card] == NULL)
140 snd_request_card(card);
141 } else if (dev == SNDRV_MINOR_GLOBAL) {
142 /* /dev/aloadSEQ */
143 snd_request_other(minor);
144 }
145#ifndef CONFIG_SND_DYNAMIC_MINORS
146 /* /dev/snd/{controlC?,seq} */
147 mptr = snd_minors[minor];
148 if (mptr == NULL)
149#endif
150#endif
151 return -ENODEV; 160 return -ENODEV;
161 }
152 } 162 }
153 old_fops = file->f_op; 163 old_fops = file->f_op;
154 file->f_op = fops_get(mptr->f_ops); 164 file->f_op = fops_get(mptr->f_ops);
155 if (file->f_op == NULL) { 165 if (file->f_op == NULL) {
156 file->f_op = old_fops; 166 file->f_op = old_fops;
157 return -ENODEV; 167 err = -ENODEV;
158 } 168 }
159 if (file->f_op->open) 169 mutex_unlock(&sound_mutex);
170 if (err < 0)
171 return err;
172
173 if (file->f_op->open) {
160 err = file->f_op->open(inode, file); 174 err = file->f_op->open(inode, file);
161 if (err) { 175 if (err) {
162 fops_put(file->f_op); 176 fops_put(file->f_op);
163 file->f_op = fops_get(old_fops); 177 file->f_op = fops_get(old_fops);
178 }
164 } 179 }
165 fops_put(old_fops); 180 fops_put(old_fops);
166 return err; 181 return err;
167} 182}
168 183
169
170/* BKL pushdown: nasty #ifdef avoidance wrapper */
171static int snd_open(struct inode *inode, struct file *file)
172{
173 int ret;
174
175 lock_kernel();
176 ret = __snd_open(inode, file);
177 unlock_kernel();
178 return ret;
179}
180
181static const struct file_operations snd_fops = 184static const struct file_operations snd_fops =
182{ 185{
183 .owner = THIS_MODULE, 186 .owner = THIS_MODULE,
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 5040c7b862fe..13afb60999b9 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1238,6 +1238,11 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1238static int snd_timer_user_open(struct inode *inode, struct file *file) 1238static int snd_timer_user_open(struct inode *inode, struct file *file)
1239{ 1239{
1240 struct snd_timer_user *tu; 1240 struct snd_timer_user *tu;
1241 int err;
1242
1243 err = nonseekable_open(inode, file);
1244 if (err < 0)
1245 return err;
1241 1246
1242 tu = kzalloc(sizeof(*tu), GFP_KERNEL); 1247 tu = kzalloc(sizeof(*tu), GFP_KERNEL);
1243 if (tu == NULL) 1248 if (tu == NULL)
@@ -1922,6 +1927,7 @@ static const struct file_operations snd_timer_f_ops =
1922 .read = snd_timer_user_read, 1927 .read = snd_timer_user_read,
1923 .open = snd_timer_user_open, 1928 .open = snd_timer_user_open,
1924 .release = snd_timer_user_release, 1929 .release = snd_timer_user_release,
1930 .llseek = no_llseek,
1925 .poll = snd_timer_user_poll, 1931 .poll = snd_timer_user_poll,
1926 .unlocked_ioctl = snd_timer_user_ioctl, 1932 .unlocked_ioctl = snd_timer_user_ioctl,
1927 .compat_ioctl = snd_timer_user_ioctl_compat, 1933 .compat_ioctl = snd_timer_user_ioctl_compat,