diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-06-26 11:35:44 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-06-26 11:35:44 -0400 |
commit | 62ed948cb1405fe95d61d8c6445c102e0c9da0a6 (patch) | |
tree | f139adcc861a05e7cc09cdb387a271a652fc2d07 /sound/core | |
parent | 17ffc7ba6d7ea68b8d5f55a5ca1b87163e69720d (diff) | |
parent | fcc18e83e1f6fd9fa6b333735bf0fcd530655511 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'sound/core')
32 files changed, 1023 insertions, 999 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index 22565c9b9603..bb397eaa7187 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -176,6 +176,8 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask, | |||
176 | read_unlock(&card->ctl_files_rwlock); | 176 | read_unlock(&card->ctl_files_rwlock); |
177 | } | 177 | } |
178 | 178 | ||
179 | EXPORT_SYMBOL(snd_ctl_notify); | ||
180 | |||
179 | /** | 181 | /** |
180 | * snd_ctl_new - create a control instance from the template | 182 | * snd_ctl_new - create a control instance from the template |
181 | * @control: the control template | 183 | * @control: the control template |
@@ -204,6 +206,8 @@ struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, unsigned int acce | |||
204 | return kctl; | 206 | return kctl; |
205 | } | 207 | } |
206 | 208 | ||
209 | EXPORT_SYMBOL(snd_ctl_new); | ||
210 | |||
207 | /** | 211 | /** |
208 | * snd_ctl_new1 - create a control instance from the template | 212 | * snd_ctl_new1 - create a control instance from the template |
209 | * @ncontrol: the initialization record | 213 | * @ncontrol: the initialization record |
@@ -242,6 +246,8 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, | |||
242 | return snd_ctl_new(&kctl, access); | 246 | return snd_ctl_new(&kctl, access); |
243 | } | 247 | } |
244 | 248 | ||
249 | EXPORT_SYMBOL(snd_ctl_new1); | ||
250 | |||
245 | /** | 251 | /** |
246 | * snd_ctl_free_one - release the control instance | 252 | * snd_ctl_free_one - release the control instance |
247 | * @kcontrol: the control instance | 253 | * @kcontrol: the control instance |
@@ -259,6 +265,8 @@ void snd_ctl_free_one(struct snd_kcontrol *kcontrol) | |||
259 | } | 265 | } |
260 | } | 266 | } |
261 | 267 | ||
268 | EXPORT_SYMBOL(snd_ctl_free_one); | ||
269 | |||
262 | static unsigned int snd_ctl_hole_check(struct snd_card *card, | 270 | static unsigned int snd_ctl_hole_check(struct snd_card *card, |
263 | unsigned int count) | 271 | unsigned int count) |
264 | { | 272 | { |
@@ -347,6 +355,8 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | |||
347 | return err; | 355 | return err; |
348 | } | 356 | } |
349 | 357 | ||
358 | EXPORT_SYMBOL(snd_ctl_add); | ||
359 | |||
350 | /** | 360 | /** |
351 | * snd_ctl_remove - remove the control from the card and release it | 361 | * snd_ctl_remove - remove the control from the card and release it |
352 | * @card: the card instance | 362 | * @card: the card instance |
@@ -373,6 +383,8 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol) | |||
373 | return 0; | 383 | return 0; |
374 | } | 384 | } |
375 | 385 | ||
386 | EXPORT_SYMBOL(snd_ctl_remove); | ||
387 | |||
376 | /** | 388 | /** |
377 | * snd_ctl_remove_id - remove the control of the given id and release it | 389 | * snd_ctl_remove_id - remove the control of the given id and release it |
378 | * @card: the card instance | 390 | * @card: the card instance |
@@ -399,6 +411,8 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) | |||
399 | return ret; | 411 | return ret; |
400 | } | 412 | } |
401 | 413 | ||
414 | EXPORT_SYMBOL(snd_ctl_remove_id); | ||
415 | |||
402 | /** | 416 | /** |
403 | * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it | 417 | * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it |
404 | * @file: active control handle | 418 | * @file: active control handle |
@@ -461,6 +475,8 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id, | |||
461 | return 0; | 475 | return 0; |
462 | } | 476 | } |
463 | 477 | ||
478 | EXPORT_SYMBOL(snd_ctl_rename_id); | ||
479 | |||
464 | /** | 480 | /** |
465 | * snd_ctl_find_numid - find the control instance with the given number-id | 481 | * snd_ctl_find_numid - find the control instance with the given number-id |
466 | * @card: the card instance | 482 | * @card: the card instance |
@@ -487,6 +503,8 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi | |||
487 | return NULL; | 503 | return NULL; |
488 | } | 504 | } |
489 | 505 | ||
506 | EXPORT_SYMBOL(snd_ctl_find_numid); | ||
507 | |||
490 | /** | 508 | /** |
491 | * snd_ctl_find_id - find the control instance with the given id | 509 | * snd_ctl_find_id - find the control instance with the given id |
492 | * @card: the card instance | 510 | * @card: the card instance |
@@ -527,6 +545,8 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, | |||
527 | return NULL; | 545 | return NULL; |
528 | } | 546 | } |
529 | 547 | ||
548 | EXPORT_SYMBOL(snd_ctl_find_id); | ||
549 | |||
530 | static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, | 550 | static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, |
531 | unsigned int cmd, void __user *arg) | 551 | unsigned int cmd, void __user *arg) |
532 | { | 552 | { |
@@ -704,6 +724,8 @@ int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control) | |||
704 | return result; | 724 | return result; |
705 | } | 725 | } |
706 | 726 | ||
727 | EXPORT_SYMBOL(snd_ctl_elem_read); | ||
728 | |||
707 | static int snd_ctl_elem_read_user(struct snd_card *card, | 729 | static int snd_ctl_elem_read_user(struct snd_card *card, |
708 | struct snd_ctl_elem_value __user *_control) | 730 | struct snd_ctl_elem_value __user *_control) |
709 | { | 731 | { |
@@ -767,6 +789,8 @@ int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, | |||
767 | return result; | 789 | return result; |
768 | } | 790 | } |
769 | 791 | ||
792 | EXPORT_SYMBOL(snd_ctl_elem_write); | ||
793 | |||
770 | static int snd_ctl_elem_write_user(struct snd_ctl_file *file, | 794 | static int snd_ctl_elem_write_user(struct snd_ctl_file *file, |
771 | struct snd_ctl_elem_value __user *_control) | 795 | struct snd_ctl_elem_value __user *_control) |
772 | { | 796 | { |
@@ -1199,11 +1223,15 @@ int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn) | |||
1199 | return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls); | 1223 | return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls); |
1200 | } | 1224 | } |
1201 | 1225 | ||
1226 | EXPORT_SYMBOL(snd_ctl_register_ioctl); | ||
1227 | |||
1202 | #ifdef CONFIG_COMPAT | 1228 | #ifdef CONFIG_COMPAT |
1203 | int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn) | 1229 | int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn) |
1204 | { | 1230 | { |
1205 | return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls); | 1231 | return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls); |
1206 | } | 1232 | } |
1233 | |||
1234 | EXPORT_SYMBOL(snd_ctl_register_ioctl_compat); | ||
1207 | #endif | 1235 | #endif |
1208 | 1236 | ||
1209 | /* | 1237 | /* |
@@ -1236,12 +1264,15 @@ int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn) | |||
1236 | return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls); | 1264 | return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls); |
1237 | } | 1265 | } |
1238 | 1266 | ||
1267 | EXPORT_SYMBOL(snd_ctl_unregister_ioctl); | ||
1268 | |||
1239 | #ifdef CONFIG_COMPAT | 1269 | #ifdef CONFIG_COMPAT |
1240 | int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn) | 1270 | int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn) |
1241 | { | 1271 | { |
1242 | return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls); | 1272 | return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls); |
1243 | } | 1273 | } |
1244 | 1274 | ||
1275 | EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat); | ||
1245 | #endif | 1276 | #endif |
1246 | 1277 | ||
1247 | static int snd_ctl_fasync(int fd, struct file * file, int on) | 1278 | static int snd_ctl_fasync(int fd, struct file * file, int on) |
diff --git a/sound/core/device.c b/sound/core/device.c index b1cf6ec56784..6ce4da4a1081 100644 --- a/sound/core/device.c +++ b/sound/core/device.c | |||
@@ -63,6 +63,8 @@ int snd_device_new(struct snd_card *card, snd_device_type_t type, | |||
63 | return 0; | 63 | return 0; |
64 | } | 64 | } |
65 | 65 | ||
66 | EXPORT_SYMBOL(snd_device_new); | ||
67 | |||
66 | /** | 68 | /** |
67 | * snd_device_free - release the device from the card | 69 | * snd_device_free - release the device from the card |
68 | * @card: the card instance | 70 | * @card: the card instance |
@@ -107,6 +109,8 @@ int snd_device_free(struct snd_card *card, void *device_data) | |||
107 | return -ENXIO; | 109 | return -ENXIO; |
108 | } | 110 | } |
109 | 111 | ||
112 | EXPORT_SYMBOL(snd_device_free); | ||
113 | |||
110 | /** | 114 | /** |
111 | * snd_device_disconnect - disconnect the device | 115 | * snd_device_disconnect - disconnect the device |
112 | * @card: the card instance | 116 | * @card: the card instance |
@@ -182,6 +186,8 @@ int snd_device_register(struct snd_card *card, void *device_data) | |||
182 | return -ENXIO; | 186 | return -ENXIO; |
183 | } | 187 | } |
184 | 188 | ||
189 | EXPORT_SYMBOL(snd_device_register); | ||
190 | |||
185 | /* | 191 | /* |
186 | * register all the devices on the card. | 192 | * register all the devices on the card. |
187 | * called from init.c | 193 | * called from init.c |
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 2524e66eccdd..8bd0dcc93eba 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c | |||
@@ -486,7 +486,6 @@ static void __init snd_hwdep_proc_init(void) | |||
486 | struct snd_info_entry *entry; | 486 | struct snd_info_entry *entry; |
487 | 487 | ||
488 | if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) { | 488 | if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) { |
489 | entry->c.text.read_size = PAGE_SIZE; | ||
490 | entry->c.text.read = snd_hwdep_proc_read; | 489 | entry->c.text.read = snd_hwdep_proc_read; |
491 | if (snd_info_register(entry) < 0) { | 490 | if (snd_info_register(entry) < 0) { |
492 | snd_info_free_entry(entry); | 491 | snd_info_free_entry(entry); |
diff --git a/sound/core/info.c b/sound/core/info.c index 2582b74d3199..10c1772bf3ea 100644 --- a/sound/core/info.c +++ b/sound/core/info.c | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/vmalloc.h> | ||
25 | #include <linux/time.h> | 24 | #include <linux/time.h> |
26 | #include <linux/smp_lock.h> | 25 | #include <linux/smp_lock.h> |
27 | #include <linux/string.h> | 26 | #include <linux/string.h> |
@@ -82,6 +81,24 @@ static int snd_info_version_init(void); | |||
82 | static int snd_info_version_done(void); | 81 | static int snd_info_version_done(void); |
83 | 82 | ||
84 | 83 | ||
84 | /* resize the proc r/w buffer */ | ||
85 | static int resize_info_buffer(struct snd_info_buffer *buffer, | ||
86 | unsigned int nsize) | ||
87 | { | ||
88 | char *nbuf; | ||
89 | |||
90 | nsize = PAGE_ALIGN(nsize); | ||
91 | nbuf = kmalloc(nsize, GFP_KERNEL); | ||
92 | if (! nbuf) | ||
93 | return -ENOMEM; | ||
94 | |||
95 | memcpy(nbuf, buffer->buffer, buffer->len); | ||
96 | kfree(buffer->buffer); | ||
97 | buffer->buffer = nbuf; | ||
98 | buffer->len = nsize; | ||
99 | return 0; | ||
100 | } | ||
101 | |||
85 | /** | 102 | /** |
86 | * snd_iprintf - printf on the procfs buffer | 103 | * snd_iprintf - printf on the procfs buffer |
87 | * @buffer: the procfs buffer | 104 | * @buffer: the procfs buffer |
@@ -95,30 +112,43 @@ int snd_iprintf(struct snd_info_buffer *buffer, char *fmt,...) | |||
95 | { | 112 | { |
96 | va_list args; | 113 | va_list args; |
97 | int len, res; | 114 | int len, res; |
115 | int err = 0; | ||
98 | 116 | ||
117 | might_sleep(); | ||
99 | if (buffer->stop || buffer->error) | 118 | if (buffer->stop || buffer->error) |
100 | return 0; | 119 | return 0; |
101 | len = buffer->len - buffer->size; | 120 | len = buffer->len - buffer->size; |
102 | va_start(args, fmt); | 121 | va_start(args, fmt); |
103 | res = vsnprintf(buffer->curr, len, fmt, args); | 122 | for (;;) { |
104 | va_end(args); | 123 | res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, args); |
105 | if (res >= len) { | 124 | if (res < len) |
106 | buffer->stop = 1; | 125 | break; |
107 | return 0; | 126 | err = resize_info_buffer(buffer, buffer->len + PAGE_SIZE); |
127 | if (err < 0) | ||
128 | break; | ||
129 | len = buffer->len - buffer->size; | ||
108 | } | 130 | } |
131 | va_end(args); | ||
132 | |||
133 | if (err < 0) | ||
134 | return err; | ||
109 | buffer->curr += res; | 135 | buffer->curr += res; |
110 | buffer->size += res; | 136 | buffer->size += res; |
111 | return res; | 137 | return res; |
112 | } | 138 | } |
113 | 139 | ||
140 | EXPORT_SYMBOL(snd_iprintf); | ||
141 | |||
114 | /* | 142 | /* |
115 | 143 | ||
116 | */ | 144 | */ |
117 | 145 | ||
118 | static struct proc_dir_entry *snd_proc_root = NULL; | 146 | static struct proc_dir_entry *snd_proc_root; |
119 | struct snd_info_entry *snd_seq_root = NULL; | 147 | struct snd_info_entry *snd_seq_root; |
148 | EXPORT_SYMBOL(snd_seq_root); | ||
149 | |||
120 | #ifdef CONFIG_SND_OSSEMUL | 150 | #ifdef CONFIG_SND_OSSEMUL |
121 | struct snd_info_entry *snd_oss_root = NULL; | 151 | struct snd_info_entry *snd_oss_root; |
122 | #endif | 152 | #endif |
123 | 153 | ||
124 | static inline void snd_info_entry_prepare(struct proc_dir_entry *de) | 154 | static inline void snd_info_entry_prepare(struct proc_dir_entry *de) |
@@ -221,7 +251,7 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer | |||
221 | struct snd_info_private_data *data; | 251 | struct snd_info_private_data *data; |
222 | struct snd_info_entry *entry; | 252 | struct snd_info_entry *entry; |
223 | struct snd_info_buffer *buf; | 253 | struct snd_info_buffer *buf; |
224 | size_t size = 0; | 254 | ssize_t size = 0; |
225 | loff_t pos; | 255 | loff_t pos; |
226 | 256 | ||
227 | data = file->private_data; | 257 | data = file->private_data; |
@@ -237,14 +267,20 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer | |||
237 | buf = data->wbuffer; | 267 | buf = data->wbuffer; |
238 | if (buf == NULL) | 268 | if (buf == NULL) |
239 | return -EIO; | 269 | return -EIO; |
240 | if (pos >= buf->len) | 270 | mutex_lock(&entry->access); |
241 | return -ENOMEM; | 271 | if (pos + count >= buf->len) { |
242 | size = buf->len - pos; | 272 | if (resize_info_buffer(buf, pos + count)) { |
243 | size = min(count, size); | 273 | mutex_unlock(&entry->access); |
244 | if (copy_from_user(buf->buffer + pos, buffer, size)) | 274 | return -ENOMEM; |
275 | } | ||
276 | } | ||
277 | if (copy_from_user(buf->buffer + pos, buffer, count)) { | ||
278 | mutex_unlock(&entry->access); | ||
245 | return -EFAULT; | 279 | return -EFAULT; |
246 | if ((long)buf->size < pos + size) | 280 | } |
247 | buf->size = pos + size; | 281 | buf->size = pos + count; |
282 | mutex_unlock(&entry->access); | ||
283 | size = count; | ||
248 | break; | 284 | break; |
249 | case SNDRV_INFO_CONTENT_DATA: | 285 | case SNDRV_INFO_CONTENT_DATA: |
250 | if (entry->c.ops->write) | 286 | if (entry->c.ops->write) |
@@ -279,18 +315,14 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) | |||
279 | } | 315 | } |
280 | mode = file->f_flags & O_ACCMODE; | 316 | mode = file->f_flags & O_ACCMODE; |
281 | if (mode == O_RDONLY || mode == O_RDWR) { | 317 | if (mode == O_RDONLY || mode == O_RDWR) { |
282 | if ((entry->content == SNDRV_INFO_CONTENT_TEXT && | 318 | if ((entry->content == SNDRV_INFO_CONTENT_DATA && |
283 | !entry->c.text.read_size) || | ||
284 | (entry->content == SNDRV_INFO_CONTENT_DATA && | ||
285 | entry->c.ops->read == NULL)) { | 319 | entry->c.ops->read == NULL)) { |
286 | err = -ENODEV; | 320 | err = -ENODEV; |
287 | goto __error; | 321 | goto __error; |
288 | } | 322 | } |
289 | } | 323 | } |
290 | if (mode == O_WRONLY || mode == O_RDWR) { | 324 | if (mode == O_WRONLY || mode == O_RDWR) { |
291 | if ((entry->content == SNDRV_INFO_CONTENT_TEXT && | 325 | if ((entry->content == SNDRV_INFO_CONTENT_DATA && |
292 | !entry->c.text.write_size) || | ||
293 | (entry->content == SNDRV_INFO_CONTENT_DATA && | ||
294 | entry->c.ops->write == NULL)) { | 326 | entry->c.ops->write == NULL)) { |
295 | err = -ENODEV; | 327 | err = -ENODEV; |
296 | goto __error; | 328 | goto __error; |
@@ -306,49 +338,23 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) | |||
306 | case SNDRV_INFO_CONTENT_TEXT: | 338 | case SNDRV_INFO_CONTENT_TEXT: |
307 | if (mode == O_RDONLY || mode == O_RDWR) { | 339 | if (mode == O_RDONLY || mode == O_RDWR) { |
308 | buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); | 340 | buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); |
309 | if (buffer == NULL) { | 341 | if (buffer == NULL) |
310 | kfree(data); | 342 | goto __nomem; |
311 | err = -ENOMEM; | ||
312 | goto __error; | ||
313 | } | ||
314 | buffer->len = (entry->c.text.read_size + | ||
315 | (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); | ||
316 | buffer->buffer = vmalloc(buffer->len); | ||
317 | if (buffer->buffer == NULL) { | ||
318 | kfree(buffer); | ||
319 | kfree(data); | ||
320 | err = -ENOMEM; | ||
321 | goto __error; | ||
322 | } | ||
323 | buffer->curr = buffer->buffer; | ||
324 | data->rbuffer = buffer; | 343 | data->rbuffer = buffer; |
344 | buffer->len = PAGE_SIZE; | ||
345 | buffer->buffer = kmalloc(buffer->len, GFP_KERNEL); | ||
346 | if (buffer->buffer == NULL) | ||
347 | goto __nomem; | ||
325 | } | 348 | } |
326 | if (mode == O_WRONLY || mode == O_RDWR) { | 349 | if (mode == O_WRONLY || mode == O_RDWR) { |
327 | buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); | 350 | buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); |
328 | if (buffer == NULL) { | 351 | if (buffer == NULL) |
329 | if (mode == O_RDWR) { | 352 | goto __nomem; |
330 | vfree(data->rbuffer->buffer); | ||
331 | kfree(data->rbuffer); | ||
332 | } | ||
333 | kfree(data); | ||
334 | err = -ENOMEM; | ||
335 | goto __error; | ||
336 | } | ||
337 | buffer->len = (entry->c.text.write_size + | ||
338 | (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); | ||
339 | buffer->buffer = vmalloc(buffer->len); | ||
340 | if (buffer->buffer == NULL) { | ||
341 | if (mode == O_RDWR) { | ||
342 | vfree(data->rbuffer->buffer); | ||
343 | kfree(data->rbuffer); | ||
344 | } | ||
345 | kfree(buffer); | ||
346 | kfree(data); | ||
347 | err = -ENOMEM; | ||
348 | goto __error; | ||
349 | } | ||
350 | buffer->curr = buffer->buffer; | ||
351 | data->wbuffer = buffer; | 353 | data->wbuffer = buffer; |
354 | buffer->len = PAGE_SIZE; | ||
355 | buffer->buffer = kmalloc(buffer->len, GFP_KERNEL); | ||
356 | if (buffer->buffer == NULL) | ||
357 | goto __nomem; | ||
352 | } | 358 | } |
353 | break; | 359 | break; |
354 | case SNDRV_INFO_CONTENT_DATA: /* data */ | 360 | case SNDRV_INFO_CONTENT_DATA: /* data */ |
@@ -373,6 +379,17 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) | |||
373 | } | 379 | } |
374 | return 0; | 380 | return 0; |
375 | 381 | ||
382 | __nomem: | ||
383 | if (data->rbuffer) { | ||
384 | kfree(data->rbuffer->buffer); | ||
385 | kfree(data->rbuffer); | ||
386 | } | ||
387 | if (data->wbuffer) { | ||
388 | kfree(data->wbuffer->buffer); | ||
389 | kfree(data->wbuffer); | ||
390 | } | ||
391 | kfree(data); | ||
392 | err = -ENOMEM; | ||
376 | __error: | 393 | __error: |
377 | module_put(entry->module); | 394 | module_put(entry->module); |
378 | __error1: | 395 | __error1: |
@@ -391,11 +408,11 @@ static int snd_info_entry_release(struct inode *inode, struct file *file) | |||
391 | entry = data->entry; | 408 | entry = data->entry; |
392 | switch (entry->content) { | 409 | switch (entry->content) { |
393 | case SNDRV_INFO_CONTENT_TEXT: | 410 | case SNDRV_INFO_CONTENT_TEXT: |
394 | if (mode == O_RDONLY || mode == O_RDWR) { | 411 | if (data->rbuffer) { |
395 | vfree(data->rbuffer->buffer); | 412 | kfree(data->rbuffer->buffer); |
396 | kfree(data->rbuffer); | 413 | kfree(data->rbuffer); |
397 | } | 414 | } |
398 | if (mode == O_WRONLY || mode == O_RDWR) { | 415 | if (data->wbuffer) { |
399 | if (entry->c.text.write) { | 416 | if (entry->c.text.write) { |
400 | entry->c.text.write(entry, data->wbuffer); | 417 | entry->c.text.write(entry, data->wbuffer); |
401 | if (data->wbuffer->error) { | 418 | if (data->wbuffer->error) { |
@@ -404,7 +421,7 @@ static int snd_info_entry_release(struct inode *inode, struct file *file) | |||
404 | data->wbuffer->error); | 421 | data->wbuffer->error); |
405 | } | 422 | } |
406 | } | 423 | } |
407 | vfree(data->wbuffer->buffer); | 424 | kfree(data->wbuffer->buffer); |
408 | kfree(data->wbuffer); | 425 | kfree(data->wbuffer); |
409 | } | 426 | } |
410 | break; | 427 | break; |
@@ -664,29 +681,29 @@ int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len) | |||
664 | if (len <= 0 || buffer->stop || buffer->error) | 681 | if (len <= 0 || buffer->stop || buffer->error) |
665 | return 1; | 682 | return 1; |
666 | while (--len > 0) { | 683 | while (--len > 0) { |
667 | c = *buffer->curr++; | 684 | c = buffer->buffer[buffer->curr++]; |
668 | if (c == '\n') { | 685 | if (c == '\n') { |
669 | if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { | 686 | if (buffer->curr >= buffer->size) |
670 | buffer->stop = 1; | 687 | buffer->stop = 1; |
671 | } | ||
672 | break; | 688 | break; |
673 | } | 689 | } |
674 | *line++ = c; | 690 | *line++ = c; |
675 | if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { | 691 | if (buffer->curr >= buffer->size) { |
676 | buffer->stop = 1; | 692 | buffer->stop = 1; |
677 | break; | 693 | break; |
678 | } | 694 | } |
679 | } | 695 | } |
680 | while (c != '\n' && !buffer->stop) { | 696 | while (c != '\n' && !buffer->stop) { |
681 | c = *buffer->curr++; | 697 | c = buffer->buffer[buffer->curr++]; |
682 | if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { | 698 | if (buffer->curr >= buffer->size) |
683 | buffer->stop = 1; | 699 | buffer->stop = 1; |
684 | } | ||
685 | } | 700 | } |
686 | *line = '\0'; | 701 | *line = '\0'; |
687 | return 0; | 702 | return 0; |
688 | } | 703 | } |
689 | 704 | ||
705 | EXPORT_SYMBOL(snd_info_get_line); | ||
706 | |||
690 | /** | 707 | /** |
691 | * snd_info_get_str - parse a string token | 708 | * snd_info_get_str - parse a string token |
692 | * @dest: the buffer to store the string token | 709 | * @dest: the buffer to store the string token |
@@ -723,6 +740,8 @@ char *snd_info_get_str(char *dest, char *src, int len) | |||
723 | return src; | 740 | return src; |
724 | } | 741 | } |
725 | 742 | ||
743 | EXPORT_SYMBOL(snd_info_get_str); | ||
744 | |||
726 | /** | 745 | /** |
727 | * snd_info_create_entry - create an info entry | 746 | * snd_info_create_entry - create an info entry |
728 | * @name: the proc file name | 747 | * @name: the proc file name |
@@ -774,6 +793,8 @@ struct snd_info_entry *snd_info_create_module_entry(struct module * module, | |||
774 | return entry; | 793 | return entry; |
775 | } | 794 | } |
776 | 795 | ||
796 | EXPORT_SYMBOL(snd_info_create_module_entry); | ||
797 | |||
777 | /** | 798 | /** |
778 | * snd_info_create_card_entry - create an info entry for the given card | 799 | * snd_info_create_card_entry - create an info entry for the given card |
779 | * @card: the card instance | 800 | * @card: the card instance |
@@ -797,6 +818,8 @@ struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card, | |||
797 | return entry; | 818 | return entry; |
798 | } | 819 | } |
799 | 820 | ||
821 | EXPORT_SYMBOL(snd_info_create_card_entry); | ||
822 | |||
800 | static int snd_info_dev_free_entry(struct snd_device *device) | 823 | static int snd_info_dev_free_entry(struct snd_device *device) |
801 | { | 824 | { |
802 | struct snd_info_entry *entry = device->device_data; | 825 | struct snd_info_entry *entry = device->device_data; |
@@ -867,6 +890,8 @@ int snd_card_proc_new(struct snd_card *card, const char *name, | |||
867 | return 0; | 890 | return 0; |
868 | } | 891 | } |
869 | 892 | ||
893 | EXPORT_SYMBOL(snd_card_proc_new); | ||
894 | |||
870 | /** | 895 | /** |
871 | * snd_info_free_entry - release the info entry | 896 | * snd_info_free_entry - release the info entry |
872 | * @entry: the info entry | 897 | * @entry: the info entry |
@@ -883,6 +908,8 @@ void snd_info_free_entry(struct snd_info_entry * entry) | |||
883 | kfree(entry); | 908 | kfree(entry); |
884 | } | 909 | } |
885 | 910 | ||
911 | EXPORT_SYMBOL(snd_info_free_entry); | ||
912 | |||
886 | /** | 913 | /** |
887 | * snd_info_register - register the info entry | 914 | * snd_info_register - register the info entry |
888 | * @entry: the info entry | 915 | * @entry: the info entry |
@@ -913,6 +940,8 @@ int snd_info_register(struct snd_info_entry * entry) | |||
913 | return 0; | 940 | return 0; |
914 | } | 941 | } |
915 | 942 | ||
943 | EXPORT_SYMBOL(snd_info_register); | ||
944 | |||
916 | /** | 945 | /** |
917 | * snd_info_unregister - de-register the info entry | 946 | * snd_info_unregister - de-register the info entry |
918 | * @entry: the info entry | 947 | * @entry: the info entry |
@@ -937,11 +966,13 @@ int snd_info_unregister(struct snd_info_entry * entry) | |||
937 | return 0; | 966 | return 0; |
938 | } | 967 | } |
939 | 968 | ||
969 | EXPORT_SYMBOL(snd_info_unregister); | ||
970 | |||
940 | /* | 971 | /* |
941 | 972 | ||
942 | */ | 973 | */ |
943 | 974 | ||
944 | static struct snd_info_entry *snd_info_version_entry = NULL; | 975 | static struct snd_info_entry *snd_info_version_entry; |
945 | 976 | ||
946 | static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | 977 | static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) |
947 | { | 978 | { |
@@ -958,7 +989,6 @@ static int __init snd_info_version_init(void) | |||
958 | entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL); | 989 | entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL); |
959 | if (entry == NULL) | 990 | if (entry == NULL) |
960 | return -ENOMEM; | 991 | return -ENOMEM; |
961 | entry->c.text.read_size = 256; | ||
962 | entry->c.text.read = snd_info_version_read; | 992 | entry->c.text.read = snd_info_version_read; |
963 | if (snd_info_register(entry) < 0) { | 993 | if (snd_info_register(entry) < 0) { |
964 | snd_info_free_entry(entry); | 994 | snd_info_free_entry(entry); |
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c index f9ce854b3d11..bb2c40d0ab66 100644 --- a/sound/core/info_oss.c +++ b/sound/core/info_oss.c | |||
@@ -64,6 +64,8 @@ int snd_oss_info_register(int dev, int num, char *string) | |||
64 | return 0; | 64 | return 0; |
65 | } | 65 | } |
66 | 66 | ||
67 | EXPORT_SYMBOL(snd_oss_info_register); | ||
68 | |||
67 | extern void snd_card_info_read_oss(struct snd_info_buffer *buffer); | 69 | extern void snd_card_info_read_oss(struct snd_info_buffer *buffer); |
68 | 70 | ||
69 | static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev) | 71 | static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev) |
@@ -117,7 +119,6 @@ int snd_info_minor_register(void) | |||
117 | 119 | ||
118 | memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings)); | 120 | memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings)); |
119 | if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", snd_oss_root)) != NULL) { | 121 | if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", snd_oss_root)) != NULL) { |
120 | entry->c.text.read_size = 2048; | ||
121 | entry->c.text.read = snd_sndstat_proc_read; | 122 | entry->c.text.read = snd_sndstat_proc_read; |
122 | if (snd_info_register(entry) < 0) { | 123 | if (snd_info_register(entry) < 0) { |
123 | snd_info_free_entry(entry); | 124 | snd_info_free_entry(entry); |
diff --git a/sound/core/init.c b/sound/core/init.c index 39ed2e5bb0af..4d9258884e44 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -38,12 +38,15 @@ struct snd_shutdown_f_ops { | |||
38 | struct snd_shutdown_f_ops *next; | 38 | struct snd_shutdown_f_ops *next; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | unsigned int snd_cards_lock = 0; /* locked for registering/using */ | 41 | static unsigned int snd_cards_lock; /* locked for registering/using */ |
42 | struct snd_card *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL}; | 42 | struct snd_card *snd_cards[SNDRV_CARDS]; |
43 | DEFINE_RWLOCK(snd_card_rwlock); | 43 | EXPORT_SYMBOL(snd_cards); |
44 | |||
45 | static DEFINE_MUTEX(snd_card_mutex); | ||
44 | 46 | ||
45 | #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) | 47 | #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) |
46 | int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag); | 48 | int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag); |
49 | EXPORT_SYMBOL(snd_mixer_oss_notify_callback); | ||
47 | #endif | 50 | #endif |
48 | 51 | ||
49 | #ifdef CONFIG_PROC_FS | 52 | #ifdef CONFIG_PROC_FS |
@@ -66,7 +69,6 @@ static inline int init_info_for_card(struct snd_card *card) | |||
66 | snd_printd("unable to create card entry\n"); | 69 | snd_printd("unable to create card entry\n"); |
67 | return err; | 70 | return err; |
68 | } | 71 | } |
69 | entry->c.text.read_size = PAGE_SIZE; | ||
70 | entry->c.text.read = snd_card_id_read; | 72 | entry->c.text.read = snd_card_id_read; |
71 | if (snd_info_register(entry) < 0) { | 73 | if (snd_info_register(entry) < 0) { |
72 | snd_info_free_entry(entry); | 74 | snd_info_free_entry(entry); |
@@ -110,7 +112,7 @@ struct snd_card *snd_card_new(int idx, const char *xid, | |||
110 | strlcpy(card->id, xid, sizeof(card->id)); | 112 | strlcpy(card->id, xid, sizeof(card->id)); |
111 | } | 113 | } |
112 | err = 0; | 114 | err = 0; |
113 | write_lock(&snd_card_rwlock); | 115 | mutex_lock(&snd_card_mutex); |
114 | if (idx < 0) { | 116 | if (idx < 0) { |
115 | int idx2; | 117 | int idx2; |
116 | for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) | 118 | for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) |
@@ -128,12 +130,12 @@ struct snd_card *snd_card_new(int idx, const char *xid, | |||
128 | else | 130 | else |
129 | err = -ENODEV; | 131 | err = -ENODEV; |
130 | if (idx < 0 || err < 0) { | 132 | if (idx < 0 || err < 0) { |
131 | write_unlock(&snd_card_rwlock); | 133 | mutex_unlock(&snd_card_mutex); |
132 | snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1); | 134 | snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1); |
133 | goto __error; | 135 | goto __error; |
134 | } | 136 | } |
135 | snd_cards_lock |= 1 << idx; /* lock it */ | 137 | snd_cards_lock |= 1 << idx; /* lock it */ |
136 | write_unlock(&snd_card_rwlock); | 138 | mutex_unlock(&snd_card_mutex); |
137 | card->number = idx; | 139 | card->number = idx; |
138 | card->module = module; | 140 | card->module = module; |
139 | INIT_LIST_HEAD(&card->devices); | 141 | INIT_LIST_HEAD(&card->devices); |
@@ -169,6 +171,19 @@ struct snd_card *snd_card_new(int idx, const char *xid, | |||
169 | return NULL; | 171 | return NULL; |
170 | } | 172 | } |
171 | 173 | ||
174 | EXPORT_SYMBOL(snd_card_new); | ||
175 | |||
176 | /* return non-zero if a card is already locked */ | ||
177 | int snd_card_locked(int card) | ||
178 | { | ||
179 | int locked; | ||
180 | |||
181 | mutex_lock(&snd_card_mutex); | ||
182 | locked = snd_cards_lock & (1 << card); | ||
183 | mutex_unlock(&snd_card_mutex); | ||
184 | return locked; | ||
185 | } | ||
186 | |||
172 | static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig) | 187 | static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig) |
173 | { | 188 | { |
174 | return -ENODEV; | 189 | return -ENODEV; |
@@ -236,9 +251,9 @@ int snd_card_disconnect(struct snd_card *card) | |||
236 | spin_unlock(&card->files_lock); | 251 | spin_unlock(&card->files_lock); |
237 | 252 | ||
238 | /* phase 1: disable fops (user space) operations for ALSA API */ | 253 | /* phase 1: disable fops (user space) operations for ALSA API */ |
239 | write_lock(&snd_card_rwlock); | 254 | mutex_lock(&snd_card_mutex); |
240 | snd_cards[card->number] = NULL; | 255 | snd_cards[card->number] = NULL; |
241 | write_unlock(&snd_card_rwlock); | 256 | mutex_unlock(&snd_card_mutex); |
242 | 257 | ||
243 | /* phase 2: replace file->f_op with special dummy operations */ | 258 | /* phase 2: replace file->f_op with special dummy operations */ |
244 | 259 | ||
@@ -298,6 +313,8 @@ int snd_card_disconnect(struct snd_card *card) | |||
298 | return 0; | 313 | return 0; |
299 | } | 314 | } |
300 | 315 | ||
316 | EXPORT_SYMBOL(snd_card_disconnect); | ||
317 | |||
301 | /** | 318 | /** |
302 | * snd_card_free - frees given soundcard structure | 319 | * snd_card_free - frees given soundcard structure |
303 | * @card: soundcard structure | 320 | * @card: soundcard structure |
@@ -315,9 +332,9 @@ int snd_card_free(struct snd_card *card) | |||
315 | 332 | ||
316 | if (card == NULL) | 333 | if (card == NULL) |
317 | return -EINVAL; | 334 | return -EINVAL; |
318 | write_lock(&snd_card_rwlock); | 335 | mutex_lock(&snd_card_mutex); |
319 | snd_cards[card->number] = NULL; | 336 | snd_cards[card->number] = NULL; |
320 | write_unlock(&snd_card_rwlock); | 337 | mutex_unlock(&snd_card_mutex); |
321 | 338 | ||
322 | #ifdef CONFIG_PM | 339 | #ifdef CONFIG_PM |
323 | wake_up(&card->power_sleep); | 340 | wake_up(&card->power_sleep); |
@@ -353,13 +370,15 @@ int snd_card_free(struct snd_card *card) | |||
353 | card->s_f_ops = s_f_ops->next; | 370 | card->s_f_ops = s_f_ops->next; |
354 | kfree(s_f_ops); | 371 | kfree(s_f_ops); |
355 | } | 372 | } |
356 | write_lock(&snd_card_rwlock); | 373 | mutex_lock(&snd_card_mutex); |
357 | snd_cards_lock &= ~(1 << card->number); | 374 | snd_cards_lock &= ~(1 << card->number); |
358 | write_unlock(&snd_card_rwlock); | 375 | mutex_unlock(&snd_card_mutex); |
359 | kfree(card); | 376 | kfree(card); |
360 | return 0; | 377 | return 0; |
361 | } | 378 | } |
362 | 379 | ||
380 | EXPORT_SYMBOL(snd_card_free); | ||
381 | |||
363 | static void snd_card_free_thread(void * __card) | 382 | static void snd_card_free_thread(void * __card) |
364 | { | 383 | { |
365 | struct snd_card *card = __card; | 384 | struct snd_card *card = __card; |
@@ -405,6 +424,8 @@ int snd_card_free_in_thread(struct snd_card *card) | |||
405 | return -EFAULT; | 424 | return -EFAULT; |
406 | } | 425 | } |
407 | 426 | ||
427 | EXPORT_SYMBOL(snd_card_free_in_thread); | ||
428 | |||
408 | static void choose_default_id(struct snd_card *card) | 429 | static void choose_default_id(struct snd_card *card) |
409 | { | 430 | { |
410 | int i, len, idx_flag = 0, loops = SNDRV_CARDS; | 431 | int i, len, idx_flag = 0, loops = SNDRV_CARDS; |
@@ -487,16 +508,16 @@ int snd_card_register(struct snd_card *card) | |||
487 | snd_assert(card != NULL, return -EINVAL); | 508 | snd_assert(card != NULL, return -EINVAL); |
488 | if ((err = snd_device_register_all(card)) < 0) | 509 | if ((err = snd_device_register_all(card)) < 0) |
489 | return err; | 510 | return err; |
490 | write_lock(&snd_card_rwlock); | 511 | mutex_lock(&snd_card_mutex); |
491 | if (snd_cards[card->number]) { | 512 | if (snd_cards[card->number]) { |
492 | /* already registered */ | 513 | /* already registered */ |
493 | write_unlock(&snd_card_rwlock); | 514 | mutex_unlock(&snd_card_mutex); |
494 | return 0; | 515 | return 0; |
495 | } | 516 | } |
496 | if (card->id[0] == '\0') | 517 | if (card->id[0] == '\0') |
497 | choose_default_id(card); | 518 | choose_default_id(card); |
498 | snd_cards[card->number] = card; | 519 | snd_cards[card->number] = card; |
499 | write_unlock(&snd_card_rwlock); | 520 | mutex_unlock(&snd_card_mutex); |
500 | init_info_for_card(card); | 521 | init_info_for_card(card); |
501 | #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) | 522 | #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) |
502 | if (snd_mixer_oss_notify_callback) | 523 | if (snd_mixer_oss_notify_callback) |
@@ -505,8 +526,10 @@ int snd_card_register(struct snd_card *card) | |||
505 | return 0; | 526 | return 0; |
506 | } | 527 | } |
507 | 528 | ||
529 | EXPORT_SYMBOL(snd_card_register); | ||
530 | |||
508 | #ifdef CONFIG_PROC_FS | 531 | #ifdef CONFIG_PROC_FS |
509 | static struct snd_info_entry *snd_card_info_entry = NULL; | 532 | static struct snd_info_entry *snd_card_info_entry; |
510 | 533 | ||
511 | static void snd_card_info_read(struct snd_info_entry *entry, | 534 | static void snd_card_info_read(struct snd_info_entry *entry, |
512 | struct snd_info_buffer *buffer) | 535 | struct snd_info_buffer *buffer) |
@@ -515,7 +538,7 @@ static void snd_card_info_read(struct snd_info_entry *entry, | |||
515 | struct snd_card *card; | 538 | struct snd_card *card; |
516 | 539 | ||
517 | for (idx = count = 0; idx < SNDRV_CARDS; idx++) { | 540 | for (idx = count = 0; idx < SNDRV_CARDS; idx++) { |
518 | read_lock(&snd_card_rwlock); | 541 | mutex_lock(&snd_card_mutex); |
519 | if ((card = snd_cards[idx]) != NULL) { | 542 | if ((card = snd_cards[idx]) != NULL) { |
520 | count++; | 543 | count++; |
521 | snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n", | 544 | snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n", |
@@ -526,7 +549,7 @@ static void snd_card_info_read(struct snd_info_entry *entry, | |||
526 | snd_iprintf(buffer, " %s\n", | 549 | snd_iprintf(buffer, " %s\n", |
527 | card->longname); | 550 | card->longname); |
528 | } | 551 | } |
529 | read_unlock(&snd_card_rwlock); | 552 | mutex_unlock(&snd_card_mutex); |
530 | } | 553 | } |
531 | if (!count) | 554 | if (!count) |
532 | snd_iprintf(buffer, "--- no soundcards ---\n"); | 555 | snd_iprintf(buffer, "--- no soundcards ---\n"); |
@@ -540,12 +563,12 @@ void snd_card_info_read_oss(struct snd_info_buffer *buffer) | |||
540 | struct snd_card *card; | 563 | struct snd_card *card; |
541 | 564 | ||
542 | for (idx = count = 0; idx < SNDRV_CARDS; idx++) { | 565 | for (idx = count = 0; idx < SNDRV_CARDS; idx++) { |
543 | read_lock(&snd_card_rwlock); | 566 | mutex_lock(&snd_card_mutex); |
544 | if ((card = snd_cards[idx]) != NULL) { | 567 | if ((card = snd_cards[idx]) != NULL) { |
545 | count++; | 568 | count++; |
546 | snd_iprintf(buffer, "%s\n", card->longname); | 569 | snd_iprintf(buffer, "%s\n", card->longname); |
547 | } | 570 | } |
548 | read_unlock(&snd_card_rwlock); | 571 | mutex_unlock(&snd_card_mutex); |
549 | } | 572 | } |
550 | if (!count) { | 573 | if (!count) { |
551 | snd_iprintf(buffer, "--- no soundcards ---\n"); | 574 | snd_iprintf(buffer, "--- no soundcards ---\n"); |
@@ -563,11 +586,11 @@ static void snd_card_module_info_read(struct snd_info_entry *entry, | |||
563 | struct snd_card *card; | 586 | struct snd_card *card; |
564 | 587 | ||
565 | for (idx = 0; idx < SNDRV_CARDS; idx++) { | 588 | for (idx = 0; idx < SNDRV_CARDS; idx++) { |
566 | read_lock(&snd_card_rwlock); | 589 | mutex_lock(&snd_card_mutex); |
567 | if ((card = snd_cards[idx]) != NULL) | 590 | if ((card = snd_cards[idx]) != NULL) |
568 | snd_iprintf(buffer, "%2i %s\n", | 591 | snd_iprintf(buffer, "%2i %s\n", |
569 | idx, card->module->name); | 592 | idx, card->module->name); |
570 | read_unlock(&snd_card_rwlock); | 593 | mutex_unlock(&snd_card_mutex); |
571 | } | 594 | } |
572 | } | 595 | } |
573 | #endif | 596 | #endif |
@@ -579,7 +602,6 @@ int __init snd_card_info_init(void) | |||
579 | entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL); | 602 | entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL); |
580 | if (! entry) | 603 | if (! entry) |
581 | return -ENOMEM; | 604 | return -ENOMEM; |
582 | entry->c.text.read_size = PAGE_SIZE; | ||
583 | entry->c.text.read = snd_card_info_read; | 605 | entry->c.text.read = snd_card_info_read; |
584 | if (snd_info_register(entry) < 0) { | 606 | if (snd_info_register(entry) < 0) { |
585 | snd_info_free_entry(entry); | 607 | snd_info_free_entry(entry); |
@@ -590,7 +612,6 @@ int __init snd_card_info_init(void) | |||
590 | #ifdef MODULE | 612 | #ifdef MODULE |
591 | entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL); | 613 | entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL); |
592 | if (entry) { | 614 | if (entry) { |
593 | entry->c.text.read_size = PAGE_SIZE; | ||
594 | entry->c.text.read = snd_card_module_info_read; | 615 | entry->c.text.read = snd_card_module_info_read; |
595 | if (snd_info_register(entry) < 0) | 616 | if (snd_info_register(entry) < 0) |
596 | snd_info_free_entry(entry); | 617 | snd_info_free_entry(entry); |
@@ -644,6 +665,8 @@ int snd_component_add(struct snd_card *card, const char *component) | |||
644 | return 0; | 665 | return 0; |
645 | } | 666 | } |
646 | 667 | ||
668 | EXPORT_SYMBOL(snd_component_add); | ||
669 | |||
647 | /** | 670 | /** |
648 | * snd_card_file_add - add the file to the file list of the card | 671 | * snd_card_file_add - add the file to the file list of the card |
649 | * @card: soundcard structure | 672 | * @card: soundcard structure |
@@ -676,6 +699,8 @@ int snd_card_file_add(struct snd_card *card, struct file *file) | |||
676 | return 0; | 699 | return 0; |
677 | } | 700 | } |
678 | 701 | ||
702 | EXPORT_SYMBOL(snd_card_file_add); | ||
703 | |||
679 | /** | 704 | /** |
680 | * snd_card_file_remove - remove the file from the file list | 705 | * snd_card_file_remove - remove the file from the file list |
681 | * @card: soundcard structure | 706 | * @card: soundcard structure |
@@ -717,6 +742,8 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) | |||
717 | return 0; | 742 | return 0; |
718 | } | 743 | } |
719 | 744 | ||
745 | EXPORT_SYMBOL(snd_card_file_remove); | ||
746 | |||
720 | #ifdef CONFIG_PM | 747 | #ifdef CONFIG_PM |
721 | /** | 748 | /** |
722 | * snd_power_wait - wait until the power-state is changed. | 749 | * snd_power_wait - wait until the power-state is changed. |
@@ -753,4 +780,5 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state) | |||
753 | return result; | 780 | return result; |
754 | } | 781 | } |
755 | 782 | ||
783 | EXPORT_SYMBOL(snd_power_wait); | ||
756 | #endif /* CONFIG_PM */ | 784 | #endif /* CONFIG_PM */ |
diff --git a/sound/core/isadma.c b/sound/core/isadma.c index 1a378951da5b..d52398727f0a 100644 --- a/sound/core/isadma.c +++ b/sound/core/isadma.c | |||
@@ -56,6 +56,8 @@ void snd_dma_program(unsigned long dma, | |||
56 | release_dma_lock(flags); | 56 | release_dma_lock(flags); |
57 | } | 57 | } |
58 | 58 | ||
59 | EXPORT_SYMBOL(snd_dma_program); | ||
60 | |||
59 | /** | 61 | /** |
60 | * snd_dma_disable - stop the ISA DMA transfer | 62 | * snd_dma_disable - stop the ISA DMA transfer |
61 | * @dma: the dma number | 63 | * @dma: the dma number |
@@ -72,6 +74,8 @@ void snd_dma_disable(unsigned long dma) | |||
72 | release_dma_lock(flags); | 74 | release_dma_lock(flags); |
73 | } | 75 | } |
74 | 76 | ||
77 | EXPORT_SYMBOL(snd_dma_disable); | ||
78 | |||
75 | /** | 79 | /** |
76 | * snd_dma_pointer - return the current pointer to DMA transfer buffer in bytes | 80 | * snd_dma_pointer - return the current pointer to DMA transfer buffer in bytes |
77 | * @dma: the dma number | 81 | * @dma: the dma number |
@@ -101,3 +105,5 @@ unsigned int snd_dma_pointer(unsigned long dma, unsigned int size) | |||
101 | else | 105 | else |
102 | return size - result; | 106 | return size - result; |
103 | } | 107 | } |
108 | |||
109 | EXPORT_SYMBOL(snd_dma_pointer); | ||
diff --git a/sound/core/memory.c b/sound/core/memory.c index 862d62d2e144..fe59850be868 100644 --- a/sound/core/memory.c +++ b/sound/core/memory.c | |||
@@ -21,6 +21,7 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/config.h> | 23 | #include <linux/config.h> |
24 | #include <linux/module.h> | ||
24 | #include <asm/io.h> | 25 | #include <asm/io.h> |
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
26 | 27 | ||
@@ -55,6 +56,8 @@ int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size | |||
55 | #endif | 56 | #endif |
56 | } | 57 | } |
57 | 58 | ||
59 | EXPORT_SYMBOL(copy_to_user_fromio); | ||
60 | |||
58 | /** | 61 | /** |
59 | * copy_from_user_toio - copy data from user-space to mmio-space | 62 | * copy_from_user_toio - copy data from user-space to mmio-space |
60 | * @dst: the destination pointer on mmio-space | 63 | * @dst: the destination pointer on mmio-space |
@@ -85,3 +88,5 @@ int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size | |||
85 | return 0; | 88 | return 0; |
86 | #endif | 89 | #endif |
87 | } | 90 | } |
91 | |||
92 | EXPORT_SYMBOL(copy_from_user_toio); | ||
diff --git a/sound/core/misc.c b/sound/core/misc.c index b53e563c09e6..03fc711f4127 100644 --- a/sound/core/misc.c +++ b/sound/core/misc.c | |||
@@ -34,6 +34,8 @@ void release_and_free_resource(struct resource *res) | |||
34 | } | 34 | } |
35 | } | 35 | } |
36 | 36 | ||
37 | EXPORT_SYMBOL(release_and_free_resource); | ||
38 | |||
37 | #ifdef CONFIG_SND_VERBOSE_PRINTK | 39 | #ifdef CONFIG_SND_VERBOSE_PRINTK |
38 | void snd_verbose_printk(const char *file, int line, const char *format, ...) | 40 | void snd_verbose_printk(const char *file, int line, const char *format, ...) |
39 | { | 41 | { |
@@ -51,6 +53,8 @@ void snd_verbose_printk(const char *file, int line, const char *format, ...) | |||
51 | vprintk(format, args); | 53 | vprintk(format, args); |
52 | va_end(args); | 54 | va_end(args); |
53 | } | 55 | } |
56 | |||
57 | EXPORT_SYMBOL(snd_verbose_printk); | ||
54 | #endif | 58 | #endif |
55 | 59 | ||
56 | #if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK) | 60 | #if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK) |
@@ -71,4 +75,6 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...) | |||
71 | va_end(args); | 75 | va_end(args); |
72 | 76 | ||
73 | } | 77 | } |
78 | |||
79 | EXPORT_SYMBOL(snd_verbose_printd); | ||
74 | #endif | 80 | #endif |
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 9c68bc3f97aa..71b5080fa66d 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c | |||
@@ -1182,9 +1182,7 @@ static void snd_mixer_oss_proc_init(struct snd_mixer_oss *mixer) | |||
1182 | return; | 1182 | return; |
1183 | entry->content = SNDRV_INFO_CONTENT_TEXT; | 1183 | entry->content = SNDRV_INFO_CONTENT_TEXT; |
1184 | entry->mode = S_IFREG | S_IRUGO | S_IWUSR; | 1184 | entry->mode = S_IFREG | S_IRUGO | S_IWUSR; |
1185 | entry->c.text.read_size = 8192; | ||
1186 | entry->c.text.read = snd_mixer_oss_proc_read; | 1185 | entry->c.text.read = snd_mixer_oss_proc_read; |
1187 | entry->c.text.write_size = 8192; | ||
1188 | entry->c.text.write = snd_mixer_oss_proc_write; | 1186 | entry->c.text.write = snd_mixer_oss_proc_write; |
1189 | entry->private_data = mixer; | 1187 | entry->private_data = mixer; |
1190 | if (snd_info_register(entry) < 0) { | 1188 | if (snd_info_register(entry) < 0) { |
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index ac990bf0b48f..f5ff4f4a16ee 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
@@ -45,7 +45,7 @@ | |||
45 | 45 | ||
46 | #define OSS_ALSAEMULVER _SIOR ('M', 249, int) | 46 | #define OSS_ALSAEMULVER _SIOR ('M', 249, int) |
47 | 47 | ||
48 | static int dsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0}; | 48 | static int dsp_map[SNDRV_CARDS]; |
49 | static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; | 49 | static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; |
50 | static int nonblock_open = 1; | 50 | static int nonblock_open = 1; |
51 | 51 | ||
@@ -78,6 +78,487 @@ static inline void snd_leave_user(mm_segment_t fs) | |||
78 | set_fs(fs); | 78 | set_fs(fs); |
79 | } | 79 | } |
80 | 80 | ||
81 | /* | ||
82 | * helper functions to process hw_params | ||
83 | */ | ||
84 | static int snd_interval_refine_min(struct snd_interval *i, unsigned int min, int openmin) | ||
85 | { | ||
86 | int changed = 0; | ||
87 | if (i->min < min) { | ||
88 | i->min = min; | ||
89 | i->openmin = openmin; | ||
90 | changed = 1; | ||
91 | } else if (i->min == min && !i->openmin && openmin) { | ||
92 | i->openmin = 1; | ||
93 | changed = 1; | ||
94 | } | ||
95 | if (i->integer) { | ||
96 | if (i->openmin) { | ||
97 | i->min++; | ||
98 | i->openmin = 0; | ||
99 | } | ||
100 | } | ||
101 | if (snd_interval_checkempty(i)) { | ||
102 | snd_interval_none(i); | ||
103 | return -EINVAL; | ||
104 | } | ||
105 | return changed; | ||
106 | } | ||
107 | |||
108 | static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int openmax) | ||
109 | { | ||
110 | int changed = 0; | ||
111 | if (i->max > max) { | ||
112 | i->max = max; | ||
113 | i->openmax = openmax; | ||
114 | changed = 1; | ||
115 | } else if (i->max == max && !i->openmax && openmax) { | ||
116 | i->openmax = 1; | ||
117 | changed = 1; | ||
118 | } | ||
119 | if (i->integer) { | ||
120 | if (i->openmax) { | ||
121 | i->max--; | ||
122 | i->openmax = 0; | ||
123 | } | ||
124 | } | ||
125 | if (snd_interval_checkempty(i)) { | ||
126 | snd_interval_none(i); | ||
127 | return -EINVAL; | ||
128 | } | ||
129 | return changed; | ||
130 | } | ||
131 | |||
132 | static int snd_interval_refine_set(struct snd_interval *i, unsigned int val) | ||
133 | { | ||
134 | struct snd_interval t; | ||
135 | t.empty = 0; | ||
136 | t.min = t.max = val; | ||
137 | t.openmin = t.openmax = 0; | ||
138 | t.integer = 1; | ||
139 | return snd_interval_refine(i, &t); | ||
140 | } | ||
141 | |||
142 | /** | ||
143 | * snd_pcm_hw_param_value_min | ||
144 | * @params: the hw_params instance | ||
145 | * @var: parameter to retrieve | ||
146 | * @dir: pointer to the direction (-1,0,1) or NULL | ||
147 | * | ||
148 | * Return the minimum value for field PAR. | ||
149 | */ | ||
150 | static unsigned int | ||
151 | snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params, | ||
152 | snd_pcm_hw_param_t var, int *dir) | ||
153 | { | ||
154 | if (hw_is_mask(var)) { | ||
155 | if (dir) | ||
156 | *dir = 0; | ||
157 | return snd_mask_min(hw_param_mask_c(params, var)); | ||
158 | } | ||
159 | if (hw_is_interval(var)) { | ||
160 | const struct snd_interval *i = hw_param_interval_c(params, var); | ||
161 | if (dir) | ||
162 | *dir = i->openmin; | ||
163 | return snd_interval_min(i); | ||
164 | } | ||
165 | return -EINVAL; | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * snd_pcm_hw_param_value_max | ||
170 | * @params: the hw_params instance | ||
171 | * @var: parameter to retrieve | ||
172 | * @dir: pointer to the direction (-1,0,1) or NULL | ||
173 | * | ||
174 | * Return the maximum value for field PAR. | ||
175 | */ | ||
176 | static unsigned int | ||
177 | snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params, | ||
178 | snd_pcm_hw_param_t var, int *dir) | ||
179 | { | ||
180 | if (hw_is_mask(var)) { | ||
181 | if (dir) | ||
182 | *dir = 0; | ||
183 | return snd_mask_max(hw_param_mask_c(params, var)); | ||
184 | } | ||
185 | if (hw_is_interval(var)) { | ||
186 | const struct snd_interval *i = hw_param_interval_c(params, var); | ||
187 | if (dir) | ||
188 | *dir = - (int) i->openmax; | ||
189 | return snd_interval_max(i); | ||
190 | } | ||
191 | return -EINVAL; | ||
192 | } | ||
193 | |||
194 | static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params, | ||
195 | snd_pcm_hw_param_t var, | ||
196 | const struct snd_mask *val) | ||
197 | { | ||
198 | int changed; | ||
199 | changed = snd_mask_refine(hw_param_mask(params, var), val); | ||
200 | if (changed) { | ||
201 | params->cmask |= 1 << var; | ||
202 | params->rmask |= 1 << var; | ||
203 | } | ||
204 | return changed; | ||
205 | } | ||
206 | |||
207 | static int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm, | ||
208 | struct snd_pcm_hw_params *params, | ||
209 | snd_pcm_hw_param_t var, | ||
210 | const struct snd_mask *val) | ||
211 | { | ||
212 | int changed = _snd_pcm_hw_param_mask(params, var, val); | ||
213 | if (changed < 0) | ||
214 | return changed; | ||
215 | if (params->rmask) { | ||
216 | int err = snd_pcm_hw_refine(pcm, params); | ||
217 | if (err < 0) | ||
218 | return err; | ||
219 | } | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, | ||
224 | snd_pcm_hw_param_t var, unsigned int val, | ||
225 | int dir) | ||
226 | { | ||
227 | int changed; | ||
228 | int open = 0; | ||
229 | if (dir) { | ||
230 | if (dir > 0) { | ||
231 | open = 1; | ||
232 | } else if (dir < 0) { | ||
233 | if (val > 0) { | ||
234 | open = 1; | ||
235 | val--; | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | if (hw_is_mask(var)) | ||
240 | changed = snd_mask_refine_min(hw_param_mask(params, var), | ||
241 | val + !!open); | ||
242 | else if (hw_is_interval(var)) | ||
243 | changed = snd_interval_refine_min(hw_param_interval(params, var), | ||
244 | val, open); | ||
245 | else | ||
246 | return -EINVAL; | ||
247 | if (changed) { | ||
248 | params->cmask |= 1 << var; | ||
249 | params->rmask |= 1 << var; | ||
250 | } | ||
251 | return changed; | ||
252 | } | ||
253 | |||
254 | /** | ||
255 | * snd_pcm_hw_param_min | ||
256 | * @pcm: PCM instance | ||
257 | * @params: the hw_params instance | ||
258 | * @var: parameter to retrieve | ||
259 | * @val: minimal value | ||
260 | * @dir: pointer to the direction (-1,0,1) or NULL | ||
261 | * | ||
262 | * Inside configuration space defined by PARAMS remove from PAR all | ||
263 | * values < VAL. Reduce configuration space accordingly. | ||
264 | * Return new minimum or -EINVAL if the configuration space is empty | ||
265 | */ | ||
266 | static int snd_pcm_hw_param_min(struct snd_pcm_substream *pcm, | ||
267 | struct snd_pcm_hw_params *params, | ||
268 | snd_pcm_hw_param_t var, unsigned int val, | ||
269 | int *dir) | ||
270 | { | ||
271 | int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0); | ||
272 | if (changed < 0) | ||
273 | return changed; | ||
274 | if (params->rmask) { | ||
275 | int err = snd_pcm_hw_refine(pcm, params); | ||
276 | if (err < 0) | ||
277 | return err; | ||
278 | } | ||
279 | return snd_pcm_hw_param_value_min(params, var, dir); | ||
280 | } | ||
281 | |||
282 | static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params, | ||
283 | snd_pcm_hw_param_t var, unsigned int val, | ||
284 | int dir) | ||
285 | { | ||
286 | int changed; | ||
287 | int open = 0; | ||
288 | if (dir) { | ||
289 | if (dir < 0) { | ||
290 | open = 1; | ||
291 | } else if (dir > 0) { | ||
292 | open = 1; | ||
293 | val++; | ||
294 | } | ||
295 | } | ||
296 | if (hw_is_mask(var)) { | ||
297 | if (val == 0 && open) { | ||
298 | snd_mask_none(hw_param_mask(params, var)); | ||
299 | changed = -EINVAL; | ||
300 | } else | ||
301 | changed = snd_mask_refine_max(hw_param_mask(params, var), | ||
302 | val - !!open); | ||
303 | } else if (hw_is_interval(var)) | ||
304 | changed = snd_interval_refine_max(hw_param_interval(params, var), | ||
305 | val, open); | ||
306 | else | ||
307 | return -EINVAL; | ||
308 | if (changed) { | ||
309 | params->cmask |= 1 << var; | ||
310 | params->rmask |= 1 << var; | ||
311 | } | ||
312 | return changed; | ||
313 | } | ||
314 | |||
315 | /** | ||
316 | * snd_pcm_hw_param_max | ||
317 | * @pcm: PCM instance | ||
318 | * @params: the hw_params instance | ||
319 | * @var: parameter to retrieve | ||
320 | * @val: maximal value | ||
321 | * @dir: pointer to the direction (-1,0,1) or NULL | ||
322 | * | ||
323 | * Inside configuration space defined by PARAMS remove from PAR all | ||
324 | * values >= VAL + 1. Reduce configuration space accordingly. | ||
325 | * Return new maximum or -EINVAL if the configuration space is empty | ||
326 | */ | ||
327 | static int snd_pcm_hw_param_max(struct snd_pcm_substream *pcm, | ||
328 | struct snd_pcm_hw_params *params, | ||
329 | snd_pcm_hw_param_t var, unsigned int val, | ||
330 | int *dir) | ||
331 | { | ||
332 | int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0); | ||
333 | if (changed < 0) | ||
334 | return changed; | ||
335 | if (params->rmask) { | ||
336 | int err = snd_pcm_hw_refine(pcm, params); | ||
337 | if (err < 0) | ||
338 | return err; | ||
339 | } | ||
340 | return snd_pcm_hw_param_value_max(params, var, dir); | ||
341 | } | ||
342 | |||
343 | static int boundary_sub(int a, int adir, | ||
344 | int b, int bdir, | ||
345 | int *c, int *cdir) | ||
346 | { | ||
347 | adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0); | ||
348 | bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0); | ||
349 | *c = a - b; | ||
350 | *cdir = adir - bdir; | ||
351 | if (*cdir == -2) { | ||
352 | (*c)--; | ||
353 | } else if (*cdir == 2) { | ||
354 | (*c)++; | ||
355 | } | ||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static int boundary_lt(unsigned int a, int adir, | ||
360 | unsigned int b, int bdir) | ||
361 | { | ||
362 | if (adir < 0) { | ||
363 | a--; | ||
364 | adir = 1; | ||
365 | } else if (adir > 0) | ||
366 | adir = 1; | ||
367 | if (bdir < 0) { | ||
368 | b--; | ||
369 | bdir = 1; | ||
370 | } else if (bdir > 0) | ||
371 | bdir = 1; | ||
372 | return a < b || (a == b && adir < bdir); | ||
373 | } | ||
374 | |||
375 | /* Return 1 if min is nearer to best than max */ | ||
376 | static int boundary_nearer(int min, int mindir, | ||
377 | int best, int bestdir, | ||
378 | int max, int maxdir) | ||
379 | { | ||
380 | int dmin, dmindir; | ||
381 | int dmax, dmaxdir; | ||
382 | boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir); | ||
383 | boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir); | ||
384 | return boundary_lt(dmin, dmindir, dmax, dmaxdir); | ||
385 | } | ||
386 | |||
387 | /** | ||
388 | * snd_pcm_hw_param_near | ||
389 | * @pcm: PCM instance | ||
390 | * @params: the hw_params instance | ||
391 | * @var: parameter to retrieve | ||
392 | * @best: value to set | ||
393 | * @dir: pointer to the direction (-1,0,1) or NULL | ||
394 | * | ||
395 | * Inside configuration space defined by PARAMS set PAR to the available value | ||
396 | * nearest to VAL. Reduce configuration space accordingly. | ||
397 | * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS, | ||
398 | * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT. | ||
399 | * Return the value found. | ||
400 | */ | ||
401 | static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, | ||
402 | struct snd_pcm_hw_params *params, | ||
403 | snd_pcm_hw_param_t var, unsigned int best, | ||
404 | int *dir) | ||
405 | { | ||
406 | struct snd_pcm_hw_params *save = NULL; | ||
407 | int v; | ||
408 | unsigned int saved_min; | ||
409 | int last = 0; | ||
410 | int min, max; | ||
411 | int mindir, maxdir; | ||
412 | int valdir = dir ? *dir : 0; | ||
413 | /* FIXME */ | ||
414 | if (best > INT_MAX) | ||
415 | best = INT_MAX; | ||
416 | min = max = best; | ||
417 | mindir = maxdir = valdir; | ||
418 | if (maxdir > 0) | ||
419 | maxdir = 0; | ||
420 | else if (maxdir == 0) | ||
421 | maxdir = -1; | ||
422 | else { | ||
423 | maxdir = 1; | ||
424 | max--; | ||
425 | } | ||
426 | save = kmalloc(sizeof(*save), GFP_KERNEL); | ||
427 | if (save == NULL) | ||
428 | return -ENOMEM; | ||
429 | *save = *params; | ||
430 | saved_min = min; | ||
431 | min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir); | ||
432 | if (min >= 0) { | ||
433 | struct snd_pcm_hw_params *params1; | ||
434 | if (max < 0) | ||
435 | goto _end; | ||
436 | if ((unsigned int)min == saved_min && mindir == valdir) | ||
437 | goto _end; | ||
438 | params1 = kmalloc(sizeof(*params1), GFP_KERNEL); | ||
439 | if (params1 == NULL) { | ||
440 | kfree(save); | ||
441 | return -ENOMEM; | ||
442 | } | ||
443 | *params1 = *save; | ||
444 | max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir); | ||
445 | if (max < 0) { | ||
446 | kfree(params1); | ||
447 | goto _end; | ||
448 | } | ||
449 | if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) { | ||
450 | *params = *params1; | ||
451 | last = 1; | ||
452 | } | ||
453 | kfree(params1); | ||
454 | } else { | ||
455 | *params = *save; | ||
456 | max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir); | ||
457 | snd_assert(max >= 0, return -EINVAL); | ||
458 | last = 1; | ||
459 | } | ||
460 | _end: | ||
461 | kfree(save); | ||
462 | if (last) | ||
463 | v = snd_pcm_hw_param_last(pcm, params, var, dir); | ||
464 | else | ||
465 | v = snd_pcm_hw_param_first(pcm, params, var, dir); | ||
466 | snd_assert(v >= 0, return -EINVAL); | ||
467 | return v; | ||
468 | } | ||
469 | |||
470 | static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params, | ||
471 | snd_pcm_hw_param_t var, unsigned int val, | ||
472 | int dir) | ||
473 | { | ||
474 | int changed; | ||
475 | if (hw_is_mask(var)) { | ||
476 | struct snd_mask *m = hw_param_mask(params, var); | ||
477 | if (val == 0 && dir < 0) { | ||
478 | changed = -EINVAL; | ||
479 | snd_mask_none(m); | ||
480 | } else { | ||
481 | if (dir > 0) | ||
482 | val++; | ||
483 | else if (dir < 0) | ||
484 | val--; | ||
485 | changed = snd_mask_refine_set(hw_param_mask(params, var), val); | ||
486 | } | ||
487 | } else if (hw_is_interval(var)) { | ||
488 | struct snd_interval *i = hw_param_interval(params, var); | ||
489 | if (val == 0 && dir < 0) { | ||
490 | changed = -EINVAL; | ||
491 | snd_interval_none(i); | ||
492 | } else if (dir == 0) | ||
493 | changed = snd_interval_refine_set(i, val); | ||
494 | else { | ||
495 | struct snd_interval t; | ||
496 | t.openmin = 1; | ||
497 | t.openmax = 1; | ||
498 | t.empty = 0; | ||
499 | t.integer = 0; | ||
500 | if (dir < 0) { | ||
501 | t.min = val - 1; | ||
502 | t.max = val; | ||
503 | } else { | ||
504 | t.min = val; | ||
505 | t.max = val+1; | ||
506 | } | ||
507 | changed = snd_interval_refine(i, &t); | ||
508 | } | ||
509 | } else | ||
510 | return -EINVAL; | ||
511 | if (changed) { | ||
512 | params->cmask |= 1 << var; | ||
513 | params->rmask |= 1 << var; | ||
514 | } | ||
515 | return changed; | ||
516 | } | ||
517 | |||
518 | /** | ||
519 | * snd_pcm_hw_param_set | ||
520 | * @pcm: PCM instance | ||
521 | * @params: the hw_params instance | ||
522 | * @var: parameter to retrieve | ||
523 | * @val: value to set | ||
524 | * @dir: pointer to the direction (-1,0,1) or NULL | ||
525 | * | ||
526 | * Inside configuration space defined by PARAMS remove from PAR all | ||
527 | * values != VAL. Reduce configuration space accordingly. | ||
528 | * Return VAL or -EINVAL if the configuration space is empty | ||
529 | */ | ||
530 | static int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm, | ||
531 | struct snd_pcm_hw_params *params, | ||
532 | snd_pcm_hw_param_t var, unsigned int val, | ||
533 | int dir) | ||
534 | { | ||
535 | int changed = _snd_pcm_hw_param_set(params, var, val, dir); | ||
536 | if (changed < 0) | ||
537 | return changed; | ||
538 | if (params->rmask) { | ||
539 | int err = snd_pcm_hw_refine(pcm, params); | ||
540 | if (err < 0) | ||
541 | return err; | ||
542 | } | ||
543 | return snd_pcm_hw_param_value(params, var, NULL); | ||
544 | } | ||
545 | |||
546 | static int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params, | ||
547 | snd_pcm_hw_param_t var) | ||
548 | { | ||
549 | int changed; | ||
550 | changed = snd_interval_setinteger(hw_param_interval(params, var)); | ||
551 | if (changed) { | ||
552 | params->cmask |= 1 << var; | ||
553 | params->rmask |= 1 << var; | ||
554 | } | ||
555 | return changed; | ||
556 | } | ||
557 | |||
558 | /* | ||
559 | * plugin | ||
560 | */ | ||
561 | |||
81 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | 562 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS |
82 | static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream) | 563 | static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream) |
83 | { | 564 | { |
@@ -203,7 +684,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, | |||
203 | oss_buffer_size = snd_pcm_plug_client_size(substream, | 684 | oss_buffer_size = snd_pcm_plug_client_size(substream, |
204 | snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size; | 685 | snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size; |
205 | oss_buffer_size = 1 << ld2(oss_buffer_size); | 686 | oss_buffer_size = 1 << ld2(oss_buffer_size); |
206 | if (atomic_read(&runtime->mmap_count)) { | 687 | if (atomic_read(&substream->mmap_count)) { |
207 | if (oss_buffer_size > runtime->oss.mmap_bytes) | 688 | if (oss_buffer_size > runtime->oss.mmap_bytes) |
208 | oss_buffer_size = runtime->oss.mmap_bytes; | 689 | oss_buffer_size = runtime->oss.mmap_bytes; |
209 | } | 690 | } |
@@ -338,7 +819,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) | |||
338 | goto failure; | 819 | goto failure; |
339 | } | 820 | } |
340 | 821 | ||
341 | if (atomic_read(&runtime->mmap_count)) | 822 | if (atomic_read(&substream->mmap_count)) |
342 | direct = 1; | 823 | direct = 1; |
343 | else | 824 | else |
344 | direct = substream->oss.setup.direct; | 825 | direct = substream->oss.setup.direct; |
@@ -347,7 +828,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) | |||
347 | _snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS); | 828 | _snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS); |
348 | _snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0); | 829 | _snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0); |
349 | snd_mask_none(&mask); | 830 | snd_mask_none(&mask); |
350 | if (atomic_read(&runtime->mmap_count)) | 831 | if (atomic_read(&substream->mmap_count)) |
351 | snd_mask_set(&mask, SNDRV_PCM_ACCESS_MMAP_INTERLEAVED); | 832 | snd_mask_set(&mask, SNDRV_PCM_ACCESS_MMAP_INTERLEAVED); |
352 | else { | 833 | else { |
353 | snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_INTERLEAVED); | 834 | snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_INTERLEAVED); |
@@ -466,7 +947,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) | |||
466 | } else { | 947 | } else { |
467 | sw_params->start_threshold = runtime->boundary; | 948 | sw_params->start_threshold = runtime->boundary; |
468 | } | 949 | } |
469 | if (atomic_read(&runtime->mmap_count) || substream->stream == SNDRV_PCM_STREAM_CAPTURE) | 950 | if (atomic_read(&substream->mmap_count) || |
951 | substream->stream == SNDRV_PCM_STREAM_CAPTURE) | ||
470 | sw_params->stop_threshold = runtime->boundary; | 952 | sw_params->stop_threshold = runtime->boundary; |
471 | else | 953 | else |
472 | sw_params->stop_threshold = runtime->buffer_size; | 954 | sw_params->stop_threshold = runtime->buffer_size; |
@@ -476,7 +958,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) | |||
476 | sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? | 958 | sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? |
477 | 1 : runtime->period_size; | 959 | 1 : runtime->period_size; |
478 | sw_params->xfer_align = 1; | 960 | sw_params->xfer_align = 1; |
479 | if (atomic_read(&runtime->mmap_count) || | 961 | if (atomic_read(&substream->mmap_count) || |
480 | substream->oss.setup.nosilence) { | 962 | substream->oss.setup.nosilence) { |
481 | sw_params->silence_threshold = 0; | 963 | sw_params->silence_threshold = 0; |
482 | sw_params->silence_size = 0; | 964 | sw_params->silence_size = 0; |
@@ -820,7 +1302,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha | |||
820 | ssize_t tmp; | 1302 | ssize_t tmp; |
821 | struct snd_pcm_runtime *runtime = substream->runtime; | 1303 | struct snd_pcm_runtime *runtime = substream->runtime; |
822 | 1304 | ||
823 | if (atomic_read(&runtime->mmap_count)) | 1305 | if (atomic_read(&substream->mmap_count)) |
824 | return -ENXIO; | 1306 | return -ENXIO; |
825 | 1307 | ||
826 | if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) | 1308 | if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) |
@@ -850,7 +1332,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha | |||
850 | if (runtime->oss.period_ptr == 0 || | 1332 | if (runtime->oss.period_ptr == 0 || |
851 | runtime->oss.period_ptr == runtime->oss.buffer_used) | 1333 | runtime->oss.period_ptr == runtime->oss.buffer_used) |
852 | runtime->oss.buffer_used = 0; | 1334 | runtime->oss.buffer_used = 0; |
853 | else if ((substream->ffile->f_flags & O_NONBLOCK) != 0) | 1335 | else if ((substream->f_flags & O_NONBLOCK) != 0) |
854 | return xfer > 0 ? xfer : -EAGAIN; | 1336 | return xfer > 0 ? xfer : -EAGAIN; |
855 | } | 1337 | } |
856 | } else { | 1338 | } else { |
@@ -863,7 +1345,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha | |||
863 | buf += tmp; | 1345 | buf += tmp; |
864 | bytes -= tmp; | 1346 | bytes -= tmp; |
865 | xfer += tmp; | 1347 | xfer += tmp; |
866 | if ((substream->ffile->f_flags & O_NONBLOCK) != 0 && | 1348 | if ((substream->f_flags & O_NONBLOCK) != 0 && |
867 | tmp != runtime->oss.period_bytes) | 1349 | tmp != runtime->oss.period_bytes) |
868 | break; | 1350 | break; |
869 | } | 1351 | } |
@@ -910,7 +1392,7 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use | |||
910 | ssize_t tmp; | 1392 | ssize_t tmp; |
911 | struct snd_pcm_runtime *runtime = substream->runtime; | 1393 | struct snd_pcm_runtime *runtime = substream->runtime; |
912 | 1394 | ||
913 | if (atomic_read(&runtime->mmap_count)) | 1395 | if (atomic_read(&substream->mmap_count)) |
914 | return -ENXIO; | 1396 | return -ENXIO; |
915 | 1397 | ||
916 | if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) | 1398 | if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) |
@@ -1040,7 +1522,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) | |||
1040 | substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; | 1522 | substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; |
1041 | if (substream != NULL) { | 1523 | if (substream != NULL) { |
1042 | runtime = substream->runtime; | 1524 | runtime = substream->runtime; |
1043 | if (atomic_read(&runtime->mmap_count)) | 1525 | if (atomic_read(&substream->mmap_count)) |
1044 | goto __direct; | 1526 | goto __direct; |
1045 | if ((err = snd_pcm_oss_make_ready(substream)) < 0) | 1527 | if ((err = snd_pcm_oss_make_ready(substream)) < 0) |
1046 | return err; | 1528 | return err; |
@@ -1101,10 +1583,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) | |||
1101 | * finish sync: drain the buffer | 1583 | * finish sync: drain the buffer |
1102 | */ | 1584 | */ |
1103 | __direct: | 1585 | __direct: |
1104 | saved_f_flags = substream->ffile->f_flags; | 1586 | saved_f_flags = substream->f_flags; |
1105 | substream->ffile->f_flags &= ~O_NONBLOCK; | 1587 | substream->f_flags &= ~O_NONBLOCK; |
1106 | err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); | 1588 | err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); |
1107 | substream->ffile->f_flags = saved_f_flags; | 1589 | substream->f_flags = saved_f_flags; |
1108 | if (err < 0) | 1590 | if (err < 0) |
1109 | return err; | 1591 | return err; |
1110 | runtime->oss.prepare = 1; | 1592 | runtime->oss.prepare = 1; |
@@ -1209,7 +1691,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) | |||
1209 | 1691 | ||
1210 | if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0) | 1692 | if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0) |
1211 | return err; | 1693 | return err; |
1212 | if (atomic_read(&substream->runtime->mmap_count)) | 1694 | if (atomic_read(&substream->mmap_count)) |
1213 | direct = 1; | 1695 | direct = 1; |
1214 | else | 1696 | else |
1215 | direct = substream->oss.setup.direct; | 1697 | direct = substream->oss.setup.direct; |
@@ -1419,7 +1901,7 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr | |||
1419 | if (trigger & PCM_ENABLE_OUTPUT) { | 1901 | if (trigger & PCM_ENABLE_OUTPUT) { |
1420 | if (runtime->oss.trigger) | 1902 | if (runtime->oss.trigger) |
1421 | goto _skip1; | 1903 | goto _skip1; |
1422 | if (atomic_read(&psubstream->runtime->mmap_count)) | 1904 | if (atomic_read(&psubstream->mmap_count)) |
1423 | snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt); | 1905 | snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt); |
1424 | runtime->oss.trigger = 1; | 1906 | runtime->oss.trigger = 1; |
1425 | runtime->start_threshold = 1; | 1907 | runtime->start_threshold = 1; |
@@ -1537,7 +2019,7 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream | |||
1537 | if (err < 0) | 2019 | if (err < 0) |
1538 | return err; | 2020 | return err; |
1539 | info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); | 2021 | info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); |
1540 | if (atomic_read(&runtime->mmap_count)) { | 2022 | if (atomic_read(&substream->mmap_count)) { |
1541 | snd_pcm_sframes_t n; | 2023 | snd_pcm_sframes_t n; |
1542 | n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt; | 2024 | n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt; |
1543 | if (n < 0) | 2025 | if (n < 0) |
@@ -1683,9 +2165,9 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, | |||
1683 | substream->oss.oss = 1; | 2165 | substream->oss.oss = 1; |
1684 | substream->oss.setup = *setup; | 2166 | substream->oss.setup = *setup; |
1685 | if (setup->nonblock) | 2167 | if (setup->nonblock) |
1686 | substream->ffile->f_flags |= O_NONBLOCK; | 2168 | substream->f_flags |= O_NONBLOCK; |
1687 | else if (setup->block) | 2169 | else if (setup->block) |
1688 | substream->ffile->f_flags &= ~O_NONBLOCK; | 2170 | substream->f_flags &= ~O_NONBLOCK; |
1689 | runtime = substream->runtime; | 2171 | runtime = substream->runtime; |
1690 | runtime->oss.params = 1; | 2172 | runtime->oss.params = 1; |
1691 | runtime->oss.trigger = 1; | 2173 | runtime->oss.trigger = 1; |
@@ -1742,6 +2224,7 @@ static int snd_pcm_oss_open_file(struct file *file, | |||
1742 | (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX)) | 2224 | (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX)) |
1743 | f_mode = FMODE_WRITE; | 2225 | f_mode = FMODE_WRITE; |
1744 | 2226 | ||
2227 | file->f_flags &= ~O_APPEND; | ||
1745 | for (idx = 0; idx < 2; idx++) { | 2228 | for (idx = 0; idx < 2; idx++) { |
1746 | if (setup[idx].disable) | 2229 | if (setup[idx].disable) |
1747 | continue; | 2230 | continue; |
@@ -2059,6 +2542,7 @@ static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t coun | |||
2059 | substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; | 2542 | substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; |
2060 | if (substream == NULL) | 2543 | if (substream == NULL) |
2061 | return -ENXIO; | 2544 | return -ENXIO; |
2545 | substream->f_flags = file->f_flags & O_NONBLOCK; | ||
2062 | #ifndef OSS_DEBUG | 2546 | #ifndef OSS_DEBUG |
2063 | return snd_pcm_oss_read1(substream, buf, count); | 2547 | return snd_pcm_oss_read1(substream, buf, count); |
2064 | #else | 2548 | #else |
@@ -2080,6 +2564,7 @@ static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size | |||
2080 | substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; | 2564 | substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; |
2081 | if (substream == NULL) | 2565 | if (substream == NULL) |
2082 | return -ENXIO; | 2566 | return -ENXIO; |
2567 | substream->f_flags = file->f_flags & O_NONBLOCK; | ||
2083 | result = snd_pcm_oss_write1(substream, buf, count); | 2568 | result = snd_pcm_oss_write1(substream, buf, count); |
2084 | #ifdef OSS_DEBUG | 2569 | #ifdef OSS_DEBUG |
2085 | printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result); | 2570 | printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result); |
@@ -2090,7 +2575,7 @@ static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size | |||
2090 | static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream) | 2575 | static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream) |
2091 | { | 2576 | { |
2092 | struct snd_pcm_runtime *runtime = substream->runtime; | 2577 | struct snd_pcm_runtime *runtime = substream->runtime; |
2093 | if (atomic_read(&runtime->mmap_count)) | 2578 | if (atomic_read(&substream->mmap_count)) |
2094 | return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; | 2579 | return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; |
2095 | else | 2580 | else |
2096 | return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames; | 2581 | return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames; |
@@ -2099,7 +2584,7 @@ static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream) | |||
2099 | static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream) | 2584 | static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream) |
2100 | { | 2585 | { |
2101 | struct snd_pcm_runtime *runtime = substream->runtime; | 2586 | struct snd_pcm_runtime *runtime = substream->runtime; |
2102 | if (atomic_read(&runtime->mmap_count)) | 2587 | if (atomic_read(&substream->mmap_count)) |
2103 | return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; | 2588 | return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; |
2104 | else | 2589 | else |
2105 | return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames; | 2590 | return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames; |
@@ -2342,9 +2827,7 @@ static void snd_pcm_oss_proc_init(struct snd_pcm *pcm) | |||
2342 | if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) { | 2827 | if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) { |
2343 | entry->content = SNDRV_INFO_CONTENT_TEXT; | 2828 | entry->content = SNDRV_INFO_CONTENT_TEXT; |
2344 | entry->mode = S_IFREG | S_IRUGO | S_IWUSR; | 2829 | entry->mode = S_IFREG | S_IRUGO | S_IWUSR; |
2345 | entry->c.text.read_size = 8192; | ||
2346 | entry->c.text.read = snd_pcm_oss_proc_read; | 2830 | entry->c.text.read = snd_pcm_oss_proc_read; |
2347 | entry->c.text.write_size = 8192; | ||
2348 | entry->c.text.write = snd_pcm_oss_proc_write; | 2831 | entry->c.text.write = snd_pcm_oss_proc_write; |
2349 | entry->private_data = pstr; | 2832 | entry->private_data = pstr; |
2350 | if (snd_info_register(entry) < 0) { | 2833 | if (snd_info_register(entry) < 0) { |
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 84b00038236d..7581edd7b9ff 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -351,10 +351,8 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry, | |||
351 | snd_iprintf(buffer, "closed\n"); | 351 | snd_iprintf(buffer, "closed\n"); |
352 | return; | 352 | return; |
353 | } | 353 | } |
354 | snd_pcm_stream_lock_irq(substream); | ||
355 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { | 354 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { |
356 | snd_iprintf(buffer, "no setup\n"); | 355 | snd_iprintf(buffer, "no setup\n"); |
357 | snd_pcm_stream_unlock_irq(substream); | ||
358 | return; | 356 | return; |
359 | } | 357 | } |
360 | snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access)); | 358 | snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access)); |
@@ -375,7 +373,6 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry, | |||
375 | snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames); | 373 | snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames); |
376 | } | 374 | } |
377 | #endif | 375 | #endif |
378 | snd_pcm_stream_unlock_irq(substream); | ||
379 | } | 376 | } |
380 | 377 | ||
381 | static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, | 378 | static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, |
@@ -387,10 +384,8 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, | |||
387 | snd_iprintf(buffer, "closed\n"); | 384 | snd_iprintf(buffer, "closed\n"); |
388 | return; | 385 | return; |
389 | } | 386 | } |
390 | snd_pcm_stream_lock_irq(substream); | ||
391 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { | 387 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { |
392 | snd_iprintf(buffer, "no setup\n"); | 388 | snd_iprintf(buffer, "no setup\n"); |
393 | snd_pcm_stream_unlock_irq(substream); | ||
394 | return; | 389 | return; |
395 | } | 390 | } |
396 | snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode)); | 391 | snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode)); |
@@ -403,7 +398,6 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, | |||
403 | snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); | 398 | snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); |
404 | snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size); | 399 | snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size); |
405 | snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary); | 400 | snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary); |
406 | snd_pcm_stream_unlock_irq(substream); | ||
407 | } | 401 | } |
408 | 402 | ||
409 | static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, | 403 | static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, |
@@ -472,7 +466,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) | |||
472 | pstr->proc_root = entry; | 466 | pstr->proc_root = entry; |
473 | 467 | ||
474 | if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) { | 468 | if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) { |
475 | snd_info_set_text_ops(entry, pstr, 256, snd_pcm_stream_proc_info_read); | 469 | snd_info_set_text_ops(entry, pstr, snd_pcm_stream_proc_info_read); |
476 | if (snd_info_register(entry) < 0) { | 470 | if (snd_info_register(entry) < 0) { |
477 | snd_info_free_entry(entry); | 471 | snd_info_free_entry(entry); |
478 | entry = NULL; | 472 | entry = NULL; |
@@ -483,9 +477,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) | |||
483 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG | 477 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG |
484 | if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug", | 478 | if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug", |
485 | pstr->proc_root)) != NULL) { | 479 | pstr->proc_root)) != NULL) { |
486 | entry->c.text.read_size = 64; | ||
487 | entry->c.text.read = snd_pcm_xrun_debug_read; | 480 | entry->c.text.read = snd_pcm_xrun_debug_read; |
488 | entry->c.text.write_size = 64; | ||
489 | entry->c.text.write = snd_pcm_xrun_debug_write; | 481 | entry->c.text.write = snd_pcm_xrun_debug_write; |
490 | entry->mode |= S_IWUSR; | 482 | entry->mode |= S_IWUSR; |
491 | entry->private_data = pstr; | 483 | entry->private_data = pstr; |
@@ -537,7 +529,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) | |||
537 | substream->proc_root = entry; | 529 | substream->proc_root = entry; |
538 | 530 | ||
539 | if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) { | 531 | if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) { |
540 | snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_info_read); | 532 | snd_info_set_text_ops(entry, substream, |
533 | snd_pcm_substream_proc_info_read); | ||
541 | if (snd_info_register(entry) < 0) { | 534 | if (snd_info_register(entry) < 0) { |
542 | snd_info_free_entry(entry); | 535 | snd_info_free_entry(entry); |
543 | entry = NULL; | 536 | entry = NULL; |
@@ -546,7 +539,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) | |||
546 | substream->proc_info_entry = entry; | 539 | substream->proc_info_entry = entry; |
547 | 540 | ||
548 | if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) { | 541 | if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) { |
549 | snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_hw_params_read); | 542 | snd_info_set_text_ops(entry, substream, |
543 | snd_pcm_substream_proc_hw_params_read); | ||
550 | if (snd_info_register(entry) < 0) { | 544 | if (snd_info_register(entry) < 0) { |
551 | snd_info_free_entry(entry); | 545 | snd_info_free_entry(entry); |
552 | entry = NULL; | 546 | entry = NULL; |
@@ -555,7 +549,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) | |||
555 | substream->proc_hw_params_entry = entry; | 549 | substream->proc_hw_params_entry = entry; |
556 | 550 | ||
557 | if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) { | 551 | if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) { |
558 | snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_sw_params_read); | 552 | snd_info_set_text_ops(entry, substream, |
553 | snd_pcm_substream_proc_sw_params_read); | ||
559 | if (snd_info_register(entry) < 0) { | 554 | if (snd_info_register(entry) < 0) { |
560 | snd_info_free_entry(entry); | 555 | snd_info_free_entry(entry); |
561 | entry = NULL; | 556 | entry = NULL; |
@@ -564,7 +559,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) | |||
564 | substream->proc_sw_params_entry = entry; | 559 | substream->proc_sw_params_entry = entry; |
565 | 560 | ||
566 | if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) { | 561 | if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) { |
567 | snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_status_read); | 562 | snd_info_set_text_ops(entry, substream, |
563 | snd_pcm_substream_proc_status_read); | ||
568 | if (snd_info_register(entry) < 0) { | 564 | if (snd_info_register(entry) < 0) { |
569 | snd_info_free_entry(entry); | 565 | snd_info_free_entry(entry); |
570 | entry = NULL; | 566 | entry = NULL; |
@@ -666,11 +662,14 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) | |||
666 | INIT_LIST_HEAD(&substream->self_group.substreams); | 662 | INIT_LIST_HEAD(&substream->self_group.substreams); |
667 | list_add_tail(&substream->link_list, &substream->self_group.substreams); | 663 | list_add_tail(&substream->link_list, &substream->self_group.substreams); |
668 | spin_lock_init(&substream->timer_lock); | 664 | spin_lock_init(&substream->timer_lock); |
665 | atomic_set(&substream->mmap_count, 0); | ||
669 | prev = substream; | 666 | prev = substream; |
670 | } | 667 | } |
671 | return 0; | 668 | return 0; |
672 | } | 669 | } |
673 | 670 | ||
671 | EXPORT_SYMBOL(snd_pcm_new_stream); | ||
672 | |||
674 | /** | 673 | /** |
675 | * snd_pcm_new - create a new PCM instance | 674 | * snd_pcm_new - create a new PCM instance |
676 | * @card: the card instance | 675 | * @card: the card instance |
@@ -730,6 +729,8 @@ int snd_pcm_new(struct snd_card *card, char *id, int device, | |||
730 | return 0; | 729 | return 0; |
731 | } | 730 | } |
732 | 731 | ||
732 | EXPORT_SYMBOL(snd_pcm_new); | ||
733 | |||
733 | static void snd_pcm_free_stream(struct snd_pcm_str * pstr) | 734 | static void snd_pcm_free_stream(struct snd_pcm_str * pstr) |
734 | { | 735 | { |
735 | struct snd_pcm_substream *substream, *substream_next; | 736 | struct snd_pcm_substream *substream, *substream_next; |
@@ -829,6 +830,26 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, | |||
829 | return -EINVAL; | 830 | return -EINVAL; |
830 | } | 831 | } |
831 | 832 | ||
833 | if (file->f_flags & O_APPEND) { | ||
834 | if (prefer_subdevice < 0) { | ||
835 | if (pstr->substream_count > 1) | ||
836 | return -EINVAL; /* must be unique */ | ||
837 | substream = pstr->substream; | ||
838 | } else { | ||
839 | for (substream = pstr->substream; substream; | ||
840 | substream = substream->next) | ||
841 | if (substream->number == prefer_subdevice) | ||
842 | break; | ||
843 | } | ||
844 | if (! substream) | ||
845 | return -ENODEV; | ||
846 | if (! SUBSTREAM_BUSY(substream)) | ||
847 | return -EBADFD; | ||
848 | substream->ref_count++; | ||
849 | *rsubstream = substream; | ||
850 | return 0; | ||
851 | } | ||
852 | |||
832 | if (prefer_subdevice >= 0) { | 853 | if (prefer_subdevice >= 0) { |
833 | for (substream = pstr->substream; substream; substream = substream->next) | 854 | for (substream = pstr->substream; substream; substream = substream->next) |
834 | if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice) | 855 | if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice) |
@@ -864,7 +885,6 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, | |||
864 | memset((void*)runtime->control, 0, size); | 885 | memset((void*)runtime->control, 0, size); |
865 | 886 | ||
866 | init_waitqueue_head(&runtime->sleep); | 887 | init_waitqueue_head(&runtime->sleep); |
867 | atomic_set(&runtime->mmap_count, 0); | ||
868 | init_timer(&runtime->tick_timer); | 888 | init_timer(&runtime->tick_timer); |
869 | runtime->tick_timer.function = snd_pcm_tick_timer_func; | 889 | runtime->tick_timer.function = snd_pcm_tick_timer_func; |
870 | runtime->tick_timer.data = (unsigned long) substream; | 890 | runtime->tick_timer.data = (unsigned long) substream; |
@@ -873,7 +893,8 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, | |||
873 | 893 | ||
874 | substream->runtime = runtime; | 894 | substream->runtime = runtime; |
875 | substream->private_data = pcm->private_data; | 895 | substream->private_data = pcm->private_data; |
876 | substream->ffile = file; | 896 | substream->ref_count = 1; |
897 | substream->f_flags = file->f_flags; | ||
877 | pstr->substream_opened++; | 898 | pstr->substream_opened++; |
878 | *rsubstream = substream; | 899 | *rsubstream = substream; |
879 | return 0; | 900 | return 0; |
@@ -882,7 +903,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, | |||
882 | void snd_pcm_detach_substream(struct snd_pcm_substream *substream) | 903 | void snd_pcm_detach_substream(struct snd_pcm_substream *substream) |
883 | { | 904 | { |
884 | struct snd_pcm_runtime *runtime; | 905 | struct snd_pcm_runtime *runtime; |
885 | substream->file = NULL; | 906 | |
886 | runtime = substream->runtime; | 907 | runtime = substream->runtime; |
887 | snd_assert(runtime != NULL, return); | 908 | snd_assert(runtime != NULL, return); |
888 | if (runtime->private_free != NULL) | 909 | if (runtime->private_free != NULL) |
@@ -1022,6 +1043,8 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) | |||
1022 | return 0; | 1043 | return 0; |
1023 | } | 1044 | } |
1024 | 1045 | ||
1046 | EXPORT_SYMBOL(snd_pcm_notify); | ||
1047 | |||
1025 | #ifdef CONFIG_PROC_FS | 1048 | #ifdef CONFIG_PROC_FS |
1026 | /* | 1049 | /* |
1027 | * Info interface | 1050 | * Info interface |
@@ -1049,15 +1072,14 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry, | |||
1049 | mutex_unlock(®ister_mutex); | 1072 | mutex_unlock(®ister_mutex); |
1050 | } | 1073 | } |
1051 | 1074 | ||
1052 | static struct snd_info_entry *snd_pcm_proc_entry = NULL; | 1075 | static struct snd_info_entry *snd_pcm_proc_entry; |
1053 | 1076 | ||
1054 | static void snd_pcm_proc_init(void) | 1077 | static void snd_pcm_proc_init(void) |
1055 | { | 1078 | { |
1056 | struct snd_info_entry *entry; | 1079 | struct snd_info_entry *entry; |
1057 | 1080 | ||
1058 | if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) { | 1081 | if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) { |
1059 | snd_info_set_text_ops(entry, NULL, SNDRV_CARDS * SNDRV_PCM_DEVICES * 128, | 1082 | snd_info_set_text_ops(entry, NULL, snd_pcm_proc_read); |
1060 | snd_pcm_proc_read); | ||
1061 | if (snd_info_register(entry) < 0) { | 1083 | if (snd_info_register(entry) < 0) { |
1062 | snd_info_free_entry(entry); | 1084 | snd_info_free_entry(entry); |
1063 | entry = NULL; | 1085 | entry = NULL; |
@@ -1099,33 +1121,3 @@ static void __exit alsa_pcm_exit(void) | |||
1099 | 1121 | ||
1100 | module_init(alsa_pcm_init) | 1122 | module_init(alsa_pcm_init) |
1101 | module_exit(alsa_pcm_exit) | 1123 | module_exit(alsa_pcm_exit) |
1102 | |||
1103 | EXPORT_SYMBOL(snd_pcm_new); | ||
1104 | EXPORT_SYMBOL(snd_pcm_new_stream); | ||
1105 | EXPORT_SYMBOL(snd_pcm_notify); | ||
1106 | EXPORT_SYMBOL(snd_pcm_open_substream); | ||
1107 | EXPORT_SYMBOL(snd_pcm_release_substream); | ||
1108 | /* pcm_native.c */ | ||
1109 | EXPORT_SYMBOL(snd_pcm_link_rwlock); | ||
1110 | #ifdef CONFIG_PM | ||
1111 | EXPORT_SYMBOL(snd_pcm_suspend); | ||
1112 | EXPORT_SYMBOL(snd_pcm_suspend_all); | ||
1113 | #endif | ||
1114 | EXPORT_SYMBOL(snd_pcm_kernel_ioctl); | ||
1115 | EXPORT_SYMBOL(snd_pcm_mmap_data); | ||
1116 | #if SNDRV_PCM_INFO_MMAP_IOMEM | ||
1117 | EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); | ||
1118 | #endif | ||
1119 | /* pcm_misc.c */ | ||
1120 | EXPORT_SYMBOL(snd_pcm_format_signed); | ||
1121 | EXPORT_SYMBOL(snd_pcm_format_unsigned); | ||
1122 | EXPORT_SYMBOL(snd_pcm_format_linear); | ||
1123 | EXPORT_SYMBOL(snd_pcm_format_little_endian); | ||
1124 | EXPORT_SYMBOL(snd_pcm_format_big_endian); | ||
1125 | EXPORT_SYMBOL(snd_pcm_format_width); | ||
1126 | EXPORT_SYMBOL(snd_pcm_format_physical_width); | ||
1127 | EXPORT_SYMBOL(snd_pcm_format_size); | ||
1128 | EXPORT_SYMBOL(snd_pcm_format_silence_64); | ||
1129 | EXPORT_SYMBOL(snd_pcm_format_set_silence); | ||
1130 | EXPORT_SYMBOL(snd_pcm_build_linear_format); | ||
1131 | EXPORT_SYMBOL(snd_pcm_limit_hw_rates); | ||
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c index e5133033de5e..2b8aab6fd6cd 100644 --- a/sound/core/pcm_compat.c +++ b/sound/core/pcm_compat.c | |||
@@ -497,9 +497,9 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l | |||
497 | case SNDRV_PCM_IOCTL_LINK: | 497 | case SNDRV_PCM_IOCTL_LINK: |
498 | case SNDRV_PCM_IOCTL_UNLINK: | 498 | case SNDRV_PCM_IOCTL_UNLINK: |
499 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 499 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
500 | return snd_pcm_playback_ioctl1(substream, cmd, argp); | 500 | return snd_pcm_playback_ioctl1(file, substream, cmd, argp); |
501 | else | 501 | else |
502 | return snd_pcm_capture_ioctl1(substream, cmd, argp); | 502 | return snd_pcm_capture_ioctl1(file, substream, cmd, argp); |
503 | case SNDRV_PCM_IOCTL_HW_REFINE32: | 503 | case SNDRV_PCM_IOCTL_HW_REFINE32: |
504 | return snd_pcm_ioctl_hw_params_compat(substream, 1, argp); | 504 | return snd_pcm_ioctl_hw_params_compat(substream, 1, argp); |
505 | case SNDRV_PCM_IOCTL_HW_PARAMS32: | 505 | case SNDRV_PCM_IOCTL_HW_PARAMS32: |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index eedc6cb038bb..0bb142a28539 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -289,6 +289,7 @@ void snd_pcm_set_ops(struct snd_pcm *pcm, int direction, struct snd_pcm_ops *ops | |||
289 | substream->ops = ops; | 289 | substream->ops = ops; |
290 | } | 290 | } |
291 | 291 | ||
292 | EXPORT_SYMBOL(snd_pcm_set_ops); | ||
292 | 293 | ||
293 | /** | 294 | /** |
294 | * snd_pcm_sync - set the PCM sync id | 295 | * snd_pcm_sync - set the PCM sync id |
@@ -306,13 +307,12 @@ void snd_pcm_set_sync(struct snd_pcm_substream *substream) | |||
306 | runtime->sync.id32[3] = -1; | 307 | runtime->sync.id32[3] = -1; |
307 | } | 308 | } |
308 | 309 | ||
310 | EXPORT_SYMBOL(snd_pcm_set_sync); | ||
311 | |||
309 | /* | 312 | /* |
310 | * Standard ioctl routine | 313 | * Standard ioctl routine |
311 | */ | 314 | */ |
312 | 315 | ||
313 | /* Code taken from alsa-lib */ | ||
314 | #define assert(a) snd_assert((a), return -EINVAL) | ||
315 | |||
316 | static inline unsigned int div32(unsigned int a, unsigned int b, | 316 | static inline unsigned int div32(unsigned int a, unsigned int b, |
317 | unsigned int *r) | 317 | unsigned int *r) |
318 | { | 318 | { |
@@ -369,56 +369,6 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b, | |||
369 | return n; | 369 | return n; |
370 | } | 370 | } |
371 | 371 | ||
372 | static int snd_interval_refine_min(struct snd_interval *i, unsigned int min, int openmin) | ||
373 | { | ||
374 | int changed = 0; | ||
375 | assert(!snd_interval_empty(i)); | ||
376 | if (i->min < min) { | ||
377 | i->min = min; | ||
378 | i->openmin = openmin; | ||
379 | changed = 1; | ||
380 | } else if (i->min == min && !i->openmin && openmin) { | ||
381 | i->openmin = 1; | ||
382 | changed = 1; | ||
383 | } | ||
384 | if (i->integer) { | ||
385 | if (i->openmin) { | ||
386 | i->min++; | ||
387 | i->openmin = 0; | ||
388 | } | ||
389 | } | ||
390 | if (snd_interval_checkempty(i)) { | ||
391 | snd_interval_none(i); | ||
392 | return -EINVAL; | ||
393 | } | ||
394 | return changed; | ||
395 | } | ||
396 | |||
397 | static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int openmax) | ||
398 | { | ||
399 | int changed = 0; | ||
400 | assert(!snd_interval_empty(i)); | ||
401 | if (i->max > max) { | ||
402 | i->max = max; | ||
403 | i->openmax = openmax; | ||
404 | changed = 1; | ||
405 | } else if (i->max == max && !i->openmax && openmax) { | ||
406 | i->openmax = 1; | ||
407 | changed = 1; | ||
408 | } | ||
409 | if (i->integer) { | ||
410 | if (i->openmax) { | ||
411 | i->max--; | ||
412 | i->openmax = 0; | ||
413 | } | ||
414 | } | ||
415 | if (snd_interval_checkempty(i)) { | ||
416 | snd_interval_none(i); | ||
417 | return -EINVAL; | ||
418 | } | ||
419 | return changed; | ||
420 | } | ||
421 | |||
422 | /** | 372 | /** |
423 | * snd_interval_refine - refine the interval value of configurator | 373 | * snd_interval_refine - refine the interval value of configurator |
424 | * @i: the interval value to refine | 374 | * @i: the interval value to refine |
@@ -433,7 +383,7 @@ static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int | |||
433 | int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) | 383 | int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) |
434 | { | 384 | { |
435 | int changed = 0; | 385 | int changed = 0; |
436 | assert(!snd_interval_empty(i)); | 386 | snd_assert(!snd_interval_empty(i), return -EINVAL); |
437 | if (i->min < v->min) { | 387 | if (i->min < v->min) { |
438 | i->min = v->min; | 388 | i->min = v->min; |
439 | i->openmin = v->openmin; | 389 | i->openmin = v->openmin; |
@@ -472,9 +422,11 @@ int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) | |||
472 | return changed; | 422 | return changed; |
473 | } | 423 | } |
474 | 424 | ||
425 | EXPORT_SYMBOL(snd_interval_refine); | ||
426 | |||
475 | static int snd_interval_refine_first(struct snd_interval *i) | 427 | static int snd_interval_refine_first(struct snd_interval *i) |
476 | { | 428 | { |
477 | assert(!snd_interval_empty(i)); | 429 | snd_assert(!snd_interval_empty(i), return -EINVAL); |
478 | if (snd_interval_single(i)) | 430 | if (snd_interval_single(i)) |
479 | return 0; | 431 | return 0; |
480 | i->max = i->min; | 432 | i->max = i->min; |
@@ -486,7 +438,7 @@ static int snd_interval_refine_first(struct snd_interval *i) | |||
486 | 438 | ||
487 | static int snd_interval_refine_last(struct snd_interval *i) | 439 | static int snd_interval_refine_last(struct snd_interval *i) |
488 | { | 440 | { |
489 | assert(!snd_interval_empty(i)); | 441 | snd_assert(!snd_interval_empty(i), return -EINVAL); |
490 | if (snd_interval_single(i)) | 442 | if (snd_interval_single(i)) |
491 | return 0; | 443 | return 0; |
492 | i->min = i->max; | 444 | i->min = i->max; |
@@ -496,16 +448,6 @@ static int snd_interval_refine_last(struct snd_interval *i) | |||
496 | return 1; | 448 | return 1; |
497 | } | 449 | } |
498 | 450 | ||
499 | static int snd_interval_refine_set(struct snd_interval *i, unsigned int val) | ||
500 | { | ||
501 | struct snd_interval t; | ||
502 | t.empty = 0; | ||
503 | t.min = t.max = val; | ||
504 | t.openmin = t.openmax = 0; | ||
505 | t.integer = 1; | ||
506 | return snd_interval_refine(i, &t); | ||
507 | } | ||
508 | |||
509 | void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c) | 451 | void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c) |
510 | { | 452 | { |
511 | if (a->empty || b->empty) { | 453 | if (a->empty || b->empty) { |
@@ -621,7 +563,6 @@ void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k, | |||
621 | c->integer = 0; | 563 | c->integer = 0; |
622 | } | 564 | } |
623 | 565 | ||
624 | #undef assert | ||
625 | /* ---- */ | 566 | /* ---- */ |
626 | 567 | ||
627 | 568 | ||
@@ -727,6 +668,8 @@ int snd_interval_ratnum(struct snd_interval *i, | |||
727 | return err; | 668 | return err; |
728 | } | 669 | } |
729 | 670 | ||
671 | EXPORT_SYMBOL(snd_interval_ratnum); | ||
672 | |||
730 | /** | 673 | /** |
731 | * snd_interval_ratden - refine the interval value | 674 | * snd_interval_ratden - refine the interval value |
732 | * @i: interval to refine | 675 | * @i: interval to refine |
@@ -877,6 +820,8 @@ int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int * | |||
877 | return changed; | 820 | return changed; |
878 | } | 821 | } |
879 | 822 | ||
823 | EXPORT_SYMBOL(snd_interval_list); | ||
824 | |||
880 | static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step) | 825 | static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step) |
881 | { | 826 | { |
882 | unsigned int n; | 827 | unsigned int n; |
@@ -953,6 +898,8 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, | |||
953 | return 0; | 898 | return 0; |
954 | } | 899 | } |
955 | 900 | ||
901 | EXPORT_SYMBOL(snd_pcm_hw_rule_add); | ||
902 | |||
956 | /** | 903 | /** |
957 | * snd_pcm_hw_constraint_mask | 904 | * snd_pcm_hw_constraint_mask |
958 | * @runtime: PCM runtime instance | 905 | * @runtime: PCM runtime instance |
@@ -1007,6 +954,8 @@ int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_pa | |||
1007 | return snd_interval_setinteger(constrs_interval(constrs, var)); | 954 | return snd_interval_setinteger(constrs_interval(constrs, var)); |
1008 | } | 955 | } |
1009 | 956 | ||
957 | EXPORT_SYMBOL(snd_pcm_hw_constraint_integer); | ||
958 | |||
1010 | /** | 959 | /** |
1011 | * snd_pcm_hw_constraint_minmax | 960 | * snd_pcm_hw_constraint_minmax |
1012 | * @runtime: PCM runtime instance | 961 | * @runtime: PCM runtime instance |
@@ -1028,6 +977,8 @@ int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_par | |||
1028 | return snd_interval_refine(constrs_interval(constrs, var), &t); | 977 | return snd_interval_refine(constrs_interval(constrs, var), &t); |
1029 | } | 978 | } |
1030 | 979 | ||
980 | EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax); | ||
981 | |||
1031 | static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, | 982 | static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, |
1032 | struct snd_pcm_hw_rule *rule) | 983 | struct snd_pcm_hw_rule *rule) |
1033 | { | 984 | { |
@@ -1055,6 +1006,8 @@ int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, | |||
1055 | var, -1); | 1006 | var, -1); |
1056 | } | 1007 | } |
1057 | 1008 | ||
1009 | EXPORT_SYMBOL(snd_pcm_hw_constraint_list); | ||
1010 | |||
1058 | static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, | 1011 | static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, |
1059 | struct snd_pcm_hw_rule *rule) | 1012 | struct snd_pcm_hw_rule *rule) |
1060 | { | 1013 | { |
@@ -1087,6 +1040,8 @@ int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime, | |||
1087 | var, -1); | 1040 | var, -1); |
1088 | } | 1041 | } |
1089 | 1042 | ||
1043 | EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums); | ||
1044 | |||
1090 | static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params, | 1045 | static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params, |
1091 | struct snd_pcm_hw_rule *rule) | 1046 | struct snd_pcm_hw_rule *rule) |
1092 | { | 1047 | { |
@@ -1118,6 +1073,8 @@ int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime, | |||
1118 | var, -1); | 1073 | var, -1); |
1119 | } | 1074 | } |
1120 | 1075 | ||
1076 | EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens); | ||
1077 | |||
1121 | static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, | 1078 | static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, |
1122 | struct snd_pcm_hw_rule *rule) | 1079 | struct snd_pcm_hw_rule *rule) |
1123 | { | 1080 | { |
@@ -1149,6 +1106,8 @@ int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime, | |||
1149 | SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); | 1106 | SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); |
1150 | } | 1107 | } |
1151 | 1108 | ||
1109 | EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits); | ||
1110 | |||
1152 | static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params, | 1111 | static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params, |
1153 | struct snd_pcm_hw_rule *rule) | 1112 | struct snd_pcm_hw_rule *rule) |
1154 | { | 1113 | { |
@@ -1173,6 +1132,8 @@ int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime, | |||
1173 | var, -1); | 1132 | var, -1); |
1174 | } | 1133 | } |
1175 | 1134 | ||
1135 | EXPORT_SYMBOL(snd_pcm_hw_constraint_step); | ||
1136 | |||
1176 | static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) | 1137 | static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) |
1177 | { | 1138 | { |
1178 | static int pow2_sizes[] = { | 1139 | static int pow2_sizes[] = { |
@@ -1200,11 +1161,7 @@ int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime, | |||
1200 | var, -1); | 1161 | var, -1); |
1201 | } | 1162 | } |
1202 | 1163 | ||
1203 | /* To use the same code we have in alsa-lib */ | 1164 | EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2); |
1204 | #define assert(i) snd_assert((i), return -EINVAL) | ||
1205 | #ifndef INT_MIN | ||
1206 | #define INT_MIN ((int)((unsigned int)INT_MAX+1)) | ||
1207 | #endif | ||
1208 | 1165 | ||
1209 | static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params, | 1166 | static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params, |
1210 | snd_pcm_hw_param_t var) | 1167 | snd_pcm_hw_param_t var) |
@@ -1224,18 +1181,6 @@ static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params, | |||
1224 | snd_BUG(); | 1181 | snd_BUG(); |
1225 | } | 1182 | } |
1226 | 1183 | ||
1227 | #if 0 | ||
1228 | /* | ||
1229 | * snd_pcm_hw_param_any | ||
1230 | */ | ||
1231 | int snd_pcm_hw_param_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params, | ||
1232 | snd_pcm_hw_param_t var) | ||
1233 | { | ||
1234 | _snd_pcm_hw_param_any(params, var); | ||
1235 | return snd_pcm_hw_refine(pcm, params); | ||
1236 | } | ||
1237 | #endif /* 0 */ | ||
1238 | |||
1239 | void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params) | 1184 | void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params) |
1240 | { | 1185 | { |
1241 | unsigned int k; | 1186 | unsigned int k; |
@@ -1247,18 +1192,7 @@ void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params) | |||
1247 | params->info = ~0U; | 1192 | params->info = ~0U; |
1248 | } | 1193 | } |
1249 | 1194 | ||
1250 | #if 0 | 1195 | EXPORT_SYMBOL(_snd_pcm_hw_params_any); |
1251 | /* | ||
1252 | * snd_pcm_hw_params_any | ||
1253 | * | ||
1254 | * Fill PARAMS with full configuration space boundaries | ||
1255 | */ | ||
1256 | int snd_pcm_hw_params_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params) | ||
1257 | { | ||
1258 | _snd_pcm_hw_params_any(params); | ||
1259 | return snd_pcm_hw_refine(pcm, params); | ||
1260 | } | ||
1261 | #endif /* 0 */ | ||
1262 | 1196 | ||
1263 | /** | 1197 | /** |
1264 | * snd_pcm_hw_param_value | 1198 | * snd_pcm_hw_param_value |
@@ -1269,8 +1203,8 @@ int snd_pcm_hw_params_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_param | |||
1269 | * Return the value for field PAR if it's fixed in configuration space | 1203 | * Return the value for field PAR if it's fixed in configuration space |
1270 | * defined by PARAMS. Return -EINVAL otherwise | 1204 | * defined by PARAMS. Return -EINVAL otherwise |
1271 | */ | 1205 | */ |
1272 | static int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, | 1206 | int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, |
1273 | snd_pcm_hw_param_t var, int *dir) | 1207 | snd_pcm_hw_param_t var, int *dir) |
1274 | { | 1208 | { |
1275 | if (hw_is_mask(var)) { | 1209 | if (hw_is_mask(var)) { |
1276 | const struct snd_mask *mask = hw_param_mask_c(params, var); | 1210 | const struct snd_mask *mask = hw_param_mask_c(params, var); |
@@ -1288,61 +1222,10 @@ static int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, | |||
1288 | *dir = i->openmin; | 1222 | *dir = i->openmin; |
1289 | return snd_interval_value(i); | 1223 | return snd_interval_value(i); |
1290 | } | 1224 | } |
1291 | assert(0); | ||
1292 | return -EINVAL; | ||
1293 | } | ||
1294 | |||
1295 | /** | ||
1296 | * snd_pcm_hw_param_value_min | ||
1297 | * @params: the hw_params instance | ||
1298 | * @var: parameter to retrieve | ||
1299 | * @dir: pointer to the direction (-1,0,1) or NULL | ||
1300 | * | ||
1301 | * Return the minimum value for field PAR. | ||
1302 | */ | ||
1303 | unsigned int snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params, | ||
1304 | snd_pcm_hw_param_t var, int *dir) | ||
1305 | { | ||
1306 | if (hw_is_mask(var)) { | ||
1307 | if (dir) | ||
1308 | *dir = 0; | ||
1309 | return snd_mask_min(hw_param_mask_c(params, var)); | ||
1310 | } | ||
1311 | if (hw_is_interval(var)) { | ||
1312 | const struct snd_interval *i = hw_param_interval_c(params, var); | ||
1313 | if (dir) | ||
1314 | *dir = i->openmin; | ||
1315 | return snd_interval_min(i); | ||
1316 | } | ||
1317 | assert(0); | ||
1318 | return -EINVAL; | 1225 | return -EINVAL; |
1319 | } | 1226 | } |
1320 | 1227 | ||
1321 | /** | 1228 | EXPORT_SYMBOL(snd_pcm_hw_param_value); |
1322 | * snd_pcm_hw_param_value_max | ||
1323 | * @params: the hw_params instance | ||
1324 | * @var: parameter to retrieve | ||
1325 | * @dir: pointer to the direction (-1,0,1) or NULL | ||
1326 | * | ||
1327 | * Return the maximum value for field PAR. | ||
1328 | */ | ||
1329 | unsigned int snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params, | ||
1330 | snd_pcm_hw_param_t var, int *dir) | ||
1331 | { | ||
1332 | if (hw_is_mask(var)) { | ||
1333 | if (dir) | ||
1334 | *dir = 0; | ||
1335 | return snd_mask_max(hw_param_mask_c(params, var)); | ||
1336 | } | ||
1337 | if (hw_is_interval(var)) { | ||
1338 | const struct snd_interval *i = hw_param_interval_c(params, var); | ||
1339 | if (dir) | ||
1340 | *dir = - (int) i->openmax; | ||
1341 | return snd_interval_max(i); | ||
1342 | } | ||
1343 | assert(0); | ||
1344 | return -EINVAL; | ||
1345 | } | ||
1346 | 1229 | ||
1347 | void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, | 1230 | void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, |
1348 | snd_pcm_hw_param_t var) | 1231 | snd_pcm_hw_param_t var) |
@@ -1360,42 +1243,7 @@ void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, | |||
1360 | } | 1243 | } |
1361 | } | 1244 | } |
1362 | 1245 | ||
1363 | int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params, | 1246 | EXPORT_SYMBOL(_snd_pcm_hw_param_setempty); |
1364 | snd_pcm_hw_param_t var) | ||
1365 | { | ||
1366 | int changed; | ||
1367 | assert(hw_is_interval(var)); | ||
1368 | changed = snd_interval_setinteger(hw_param_interval(params, var)); | ||
1369 | if (changed) { | ||
1370 | params->cmask |= 1 << var; | ||
1371 | params->rmask |= 1 << var; | ||
1372 | } | ||
1373 | return changed; | ||
1374 | } | ||
1375 | |||
1376 | #if 0 | ||
1377 | /* | ||
1378 | * snd_pcm_hw_param_setinteger | ||
1379 | * | ||
1380 | * Inside configuration space defined by PARAMS remove from PAR all | ||
1381 | * non integer values. Reduce configuration space accordingly. | ||
1382 | * Return -EINVAL if the configuration space is empty | ||
1383 | */ | ||
1384 | int snd_pcm_hw_param_setinteger(struct snd_pcm_substream *pcm, | ||
1385 | struct snd_pcm_hw_params *params, | ||
1386 | snd_pcm_hw_param_t var) | ||
1387 | { | ||
1388 | int changed = _snd_pcm_hw_param_setinteger(params, var); | ||
1389 | if (changed < 0) | ||
1390 | return changed; | ||
1391 | if (params->rmask) { | ||
1392 | int err = snd_pcm_hw_refine(pcm, params); | ||
1393 | if (err < 0) | ||
1394 | return err; | ||
1395 | } | ||
1396 | return 0; | ||
1397 | } | ||
1398 | #endif /* 0 */ | ||
1399 | 1247 | ||
1400 | static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, | 1248 | static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, |
1401 | snd_pcm_hw_param_t var) | 1249 | snd_pcm_hw_param_t var) |
@@ -1405,10 +1253,8 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, | |||
1405 | changed = snd_mask_refine_first(hw_param_mask(params, var)); | 1253 | changed = snd_mask_refine_first(hw_param_mask(params, var)); |
1406 | else if (hw_is_interval(var)) | 1254 | else if (hw_is_interval(var)) |
1407 | changed = snd_interval_refine_first(hw_param_interval(params, var)); | 1255 | changed = snd_interval_refine_first(hw_param_interval(params, var)); |
1408 | else { | 1256 | else |
1409 | assert(0); | ||
1410 | return -EINVAL; | 1257 | return -EINVAL; |
1411 | } | ||
1412 | if (changed) { | 1258 | if (changed) { |
1413 | params->cmask |= 1 << var; | 1259 | params->cmask |= 1 << var; |
1414 | params->rmask |= 1 << var; | 1260 | params->rmask |= 1 << var; |
@@ -1428,20 +1274,22 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, | |||
1428 | * values > minimum. Reduce configuration space accordingly. | 1274 | * values > minimum. Reduce configuration space accordingly. |
1429 | * Return the minimum. | 1275 | * Return the minimum. |
1430 | */ | 1276 | */ |
1431 | static int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, | 1277 | int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, |
1432 | struct snd_pcm_hw_params *params, | 1278 | struct snd_pcm_hw_params *params, |
1433 | snd_pcm_hw_param_t var, int *dir) | 1279 | snd_pcm_hw_param_t var, int *dir) |
1434 | { | 1280 | { |
1435 | int changed = _snd_pcm_hw_param_first(params, var); | 1281 | int changed = _snd_pcm_hw_param_first(params, var); |
1436 | if (changed < 0) | 1282 | if (changed < 0) |
1437 | return changed; | 1283 | return changed; |
1438 | if (params->rmask) { | 1284 | if (params->rmask) { |
1439 | int err = snd_pcm_hw_refine(pcm, params); | 1285 | int err = snd_pcm_hw_refine(pcm, params); |
1440 | assert(err >= 0); | 1286 | snd_assert(err >= 0, return err); |
1441 | } | 1287 | } |
1442 | return snd_pcm_hw_param_value(params, var, dir); | 1288 | return snd_pcm_hw_param_value(params, var, dir); |
1443 | } | 1289 | } |
1444 | 1290 | ||
1291 | EXPORT_SYMBOL(snd_pcm_hw_param_first); | ||
1292 | |||
1445 | static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, | 1293 | static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, |
1446 | snd_pcm_hw_param_t var) | 1294 | snd_pcm_hw_param_t var) |
1447 | { | 1295 | { |
@@ -1450,10 +1298,8 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, | |||
1450 | changed = snd_mask_refine_last(hw_param_mask(params, var)); | 1298 | changed = snd_mask_refine_last(hw_param_mask(params, var)); |
1451 | else if (hw_is_interval(var)) | 1299 | else if (hw_is_interval(var)) |
1452 | changed = snd_interval_refine_last(hw_param_interval(params, var)); | 1300 | changed = snd_interval_refine_last(hw_param_interval(params, var)); |
1453 | else { | 1301 | else |
1454 | assert(0); | ||
1455 | return -EINVAL; | 1302 | return -EINVAL; |
1456 | } | ||
1457 | if (changed) { | 1303 | if (changed) { |
1458 | params->cmask |= 1 << var; | 1304 | params->cmask |= 1 << var; |
1459 | params->rmask |= 1 << var; | 1305 | params->rmask |= 1 << var; |
@@ -1473,381 +1319,21 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, | |||
1473 | * values < maximum. Reduce configuration space accordingly. | 1319 | * values < maximum. Reduce configuration space accordingly. |
1474 | * Return the maximum. | 1320 | * Return the maximum. |
1475 | */ | 1321 | */ |
1476 | static int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, | 1322 | int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, |
1477 | struct snd_pcm_hw_params *params, | 1323 | struct snd_pcm_hw_params *params, |
1478 | snd_pcm_hw_param_t var, int *dir) | 1324 | snd_pcm_hw_param_t var, int *dir) |
1479 | { | 1325 | { |
1480 | int changed = _snd_pcm_hw_param_last(params, var); | 1326 | int changed = _snd_pcm_hw_param_last(params, var); |
1481 | if (changed < 0) | 1327 | if (changed < 0) |
1482 | return changed; | 1328 | return changed; |
1483 | if (params->rmask) { | 1329 | if (params->rmask) { |
1484 | int err = snd_pcm_hw_refine(pcm, params); | 1330 | int err = snd_pcm_hw_refine(pcm, params); |
1485 | assert(err >= 0); | 1331 | snd_assert(err >= 0, return err); |
1486 | } | 1332 | } |
1487 | return snd_pcm_hw_param_value(params, var, dir); | 1333 | return snd_pcm_hw_param_value(params, var, dir); |
1488 | } | 1334 | } |
1489 | 1335 | ||
1490 | int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, | 1336 | EXPORT_SYMBOL(snd_pcm_hw_param_last); |
1491 | snd_pcm_hw_param_t var, unsigned int val, int dir) | ||
1492 | { | ||
1493 | int changed; | ||
1494 | int open = 0; | ||
1495 | if (dir) { | ||
1496 | if (dir > 0) { | ||
1497 | open = 1; | ||
1498 | } else if (dir < 0) { | ||
1499 | if (val > 0) { | ||
1500 | open = 1; | ||
1501 | val--; | ||
1502 | } | ||
1503 | } | ||
1504 | } | ||
1505 | if (hw_is_mask(var)) | ||
1506 | changed = snd_mask_refine_min(hw_param_mask(params, var), val + !!open); | ||
1507 | else if (hw_is_interval(var)) | ||
1508 | changed = snd_interval_refine_min(hw_param_interval(params, var), val, open); | ||
1509 | else { | ||
1510 | assert(0); | ||
1511 | return -EINVAL; | ||
1512 | } | ||
1513 | if (changed) { | ||
1514 | params->cmask |= 1 << var; | ||
1515 | params->rmask |= 1 << var; | ||
1516 | } | ||
1517 | return changed; | ||
1518 | } | ||
1519 | |||
1520 | /** | ||
1521 | * snd_pcm_hw_param_min | ||
1522 | * @pcm: PCM instance | ||
1523 | * @params: the hw_params instance | ||
1524 | * @var: parameter to retrieve | ||
1525 | * @val: minimal value | ||
1526 | * @dir: pointer to the direction (-1,0,1) or NULL | ||
1527 | * | ||
1528 | * Inside configuration space defined by PARAMS remove from PAR all | ||
1529 | * values < VAL. Reduce configuration space accordingly. | ||
1530 | * Return new minimum or -EINVAL if the configuration space is empty | ||
1531 | */ | ||
1532 | static int snd_pcm_hw_param_min(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params, | ||
1533 | snd_pcm_hw_param_t var, unsigned int val, | ||
1534 | int *dir) | ||
1535 | { | ||
1536 | int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0); | ||
1537 | if (changed < 0) | ||
1538 | return changed; | ||
1539 | if (params->rmask) { | ||
1540 | int err = snd_pcm_hw_refine(pcm, params); | ||
1541 | if (err < 0) | ||
1542 | return err; | ||
1543 | } | ||
1544 | return snd_pcm_hw_param_value_min(params, var, dir); | ||
1545 | } | ||
1546 | |||
1547 | static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params, | ||
1548 | snd_pcm_hw_param_t var, unsigned int val, | ||
1549 | int dir) | ||
1550 | { | ||
1551 | int changed; | ||
1552 | int open = 0; | ||
1553 | if (dir) { | ||
1554 | if (dir < 0) { | ||
1555 | open = 1; | ||
1556 | } else if (dir > 0) { | ||
1557 | open = 1; | ||
1558 | val++; | ||
1559 | } | ||
1560 | } | ||
1561 | if (hw_is_mask(var)) { | ||
1562 | if (val == 0 && open) { | ||
1563 | snd_mask_none(hw_param_mask(params, var)); | ||
1564 | changed = -EINVAL; | ||
1565 | } else | ||
1566 | changed = snd_mask_refine_max(hw_param_mask(params, var), val - !!open); | ||
1567 | } else if (hw_is_interval(var)) | ||
1568 | changed = snd_interval_refine_max(hw_param_interval(params, var), val, open); | ||
1569 | else { | ||
1570 | assert(0); | ||
1571 | return -EINVAL; | ||
1572 | } | ||
1573 | if (changed) { | ||
1574 | params->cmask |= 1 << var; | ||
1575 | params->rmask |= 1 << var; | ||
1576 | } | ||
1577 | return changed; | ||
1578 | } | ||
1579 | |||
1580 | /** | ||
1581 | * snd_pcm_hw_param_max | ||
1582 | * @pcm: PCM instance | ||
1583 | * @params: the hw_params instance | ||
1584 | * @var: parameter to retrieve | ||
1585 | * @val: maximal value | ||
1586 | * @dir: pointer to the direction (-1,0,1) or NULL | ||
1587 | * | ||
1588 | * Inside configuration space defined by PARAMS remove from PAR all | ||
1589 | * values >= VAL + 1. Reduce configuration space accordingly. | ||
1590 | * Return new maximum or -EINVAL if the configuration space is empty | ||
1591 | */ | ||
1592 | static int snd_pcm_hw_param_max(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params, | ||
1593 | snd_pcm_hw_param_t var, unsigned int val, | ||
1594 | int *dir) | ||
1595 | { | ||
1596 | int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0); | ||
1597 | if (changed < 0) | ||
1598 | return changed; | ||
1599 | if (params->rmask) { | ||
1600 | int err = snd_pcm_hw_refine(pcm, params); | ||
1601 | if (err < 0) | ||
1602 | return err; | ||
1603 | } | ||
1604 | return snd_pcm_hw_param_value_max(params, var, dir); | ||
1605 | } | ||
1606 | |||
1607 | int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params, | ||
1608 | snd_pcm_hw_param_t var, unsigned int val, int dir) | ||
1609 | { | ||
1610 | int changed; | ||
1611 | if (hw_is_mask(var)) { | ||
1612 | struct snd_mask *m = hw_param_mask(params, var); | ||
1613 | if (val == 0 && dir < 0) { | ||
1614 | changed = -EINVAL; | ||
1615 | snd_mask_none(m); | ||
1616 | } else { | ||
1617 | if (dir > 0) | ||
1618 | val++; | ||
1619 | else if (dir < 0) | ||
1620 | val--; | ||
1621 | changed = snd_mask_refine_set(hw_param_mask(params, var), val); | ||
1622 | } | ||
1623 | } else if (hw_is_interval(var)) { | ||
1624 | struct snd_interval *i = hw_param_interval(params, var); | ||
1625 | if (val == 0 && dir < 0) { | ||
1626 | changed = -EINVAL; | ||
1627 | snd_interval_none(i); | ||
1628 | } else if (dir == 0) | ||
1629 | changed = snd_interval_refine_set(i, val); | ||
1630 | else { | ||
1631 | struct snd_interval t; | ||
1632 | t.openmin = 1; | ||
1633 | t.openmax = 1; | ||
1634 | t.empty = 0; | ||
1635 | t.integer = 0; | ||
1636 | if (dir < 0) { | ||
1637 | t.min = val - 1; | ||
1638 | t.max = val; | ||
1639 | } else { | ||
1640 | t.min = val; | ||
1641 | t.max = val+1; | ||
1642 | } | ||
1643 | changed = snd_interval_refine(i, &t); | ||
1644 | } | ||
1645 | } else { | ||
1646 | assert(0); | ||
1647 | return -EINVAL; | ||
1648 | } | ||
1649 | if (changed) { | ||
1650 | params->cmask |= 1 << var; | ||
1651 | params->rmask |= 1 << var; | ||
1652 | } | ||
1653 | return changed; | ||
1654 | } | ||
1655 | |||
1656 | /** | ||
1657 | * snd_pcm_hw_param_set | ||
1658 | * @pcm: PCM instance | ||
1659 | * @params: the hw_params instance | ||
1660 | * @var: parameter to retrieve | ||
1661 | * @val: value to set | ||
1662 | * @dir: pointer to the direction (-1,0,1) or NULL | ||
1663 | * | ||
1664 | * Inside configuration space defined by PARAMS remove from PAR all | ||
1665 | * values != VAL. Reduce configuration space accordingly. | ||
1666 | * Return VAL or -EINVAL if the configuration space is empty | ||
1667 | */ | ||
1668 | int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params, | ||
1669 | snd_pcm_hw_param_t var, unsigned int val, int dir) | ||
1670 | { | ||
1671 | int changed = _snd_pcm_hw_param_set(params, var, val, dir); | ||
1672 | if (changed < 0) | ||
1673 | return changed; | ||
1674 | if (params->rmask) { | ||
1675 | int err = snd_pcm_hw_refine(pcm, params); | ||
1676 | if (err < 0) | ||
1677 | return err; | ||
1678 | } | ||
1679 | return snd_pcm_hw_param_value(params, var, NULL); | ||
1680 | } | ||
1681 | |||
1682 | static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params, | ||
1683 | snd_pcm_hw_param_t var, const struct snd_mask *val) | ||
1684 | { | ||
1685 | int changed; | ||
1686 | assert(hw_is_mask(var)); | ||
1687 | changed = snd_mask_refine(hw_param_mask(params, var), val); | ||
1688 | if (changed) { | ||
1689 | params->cmask |= 1 << var; | ||
1690 | params->rmask |= 1 << var; | ||
1691 | } | ||
1692 | return changed; | ||
1693 | } | ||
1694 | |||
1695 | /** | ||
1696 | * snd_pcm_hw_param_mask | ||
1697 | * @pcm: PCM instance | ||
1698 | * @params: the hw_params instance | ||
1699 | * @var: parameter to retrieve | ||
1700 | * @val: mask to apply | ||
1701 | * | ||
1702 | * Inside configuration space defined by PARAMS remove from PAR all values | ||
1703 | * not contained in MASK. Reduce configuration space accordingly. | ||
1704 | * This function can be called only for SNDRV_PCM_HW_PARAM_ACCESS, | ||
1705 | * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT. | ||
1706 | * Return 0 on success or -EINVAL | ||
1707 | * if the configuration space is empty | ||
1708 | */ | ||
1709 | int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params, | ||
1710 | snd_pcm_hw_param_t var, const struct snd_mask *val) | ||
1711 | { | ||
1712 | int changed = _snd_pcm_hw_param_mask(params, var, val); | ||
1713 | if (changed < 0) | ||
1714 | return changed; | ||
1715 | if (params->rmask) { | ||
1716 | int err = snd_pcm_hw_refine(pcm, params); | ||
1717 | if (err < 0) | ||
1718 | return err; | ||
1719 | } | ||
1720 | return 0; | ||
1721 | } | ||
1722 | |||
1723 | static int boundary_sub(int a, int adir, | ||
1724 | int b, int bdir, | ||
1725 | int *c, int *cdir) | ||
1726 | { | ||
1727 | adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0); | ||
1728 | bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0); | ||
1729 | *c = a - b; | ||
1730 | *cdir = adir - bdir; | ||
1731 | if (*cdir == -2) { | ||
1732 | assert(*c > INT_MIN); | ||
1733 | (*c)--; | ||
1734 | } else if (*cdir == 2) { | ||
1735 | assert(*c < INT_MAX); | ||
1736 | (*c)++; | ||
1737 | } | ||
1738 | return 0; | ||
1739 | } | ||
1740 | |||
1741 | static int boundary_lt(unsigned int a, int adir, | ||
1742 | unsigned int b, int bdir) | ||
1743 | { | ||
1744 | assert(a > 0 || adir >= 0); | ||
1745 | assert(b > 0 || bdir >= 0); | ||
1746 | if (adir < 0) { | ||
1747 | a--; | ||
1748 | adir = 1; | ||
1749 | } else if (adir > 0) | ||
1750 | adir = 1; | ||
1751 | if (bdir < 0) { | ||
1752 | b--; | ||
1753 | bdir = 1; | ||
1754 | } else if (bdir > 0) | ||
1755 | bdir = 1; | ||
1756 | return a < b || (a == b && adir < bdir); | ||
1757 | } | ||
1758 | |||
1759 | /* Return 1 if min is nearer to best than max */ | ||
1760 | static int boundary_nearer(int min, int mindir, | ||
1761 | int best, int bestdir, | ||
1762 | int max, int maxdir) | ||
1763 | { | ||
1764 | int dmin, dmindir; | ||
1765 | int dmax, dmaxdir; | ||
1766 | boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir); | ||
1767 | boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir); | ||
1768 | return boundary_lt(dmin, dmindir, dmax, dmaxdir); | ||
1769 | } | ||
1770 | |||
1771 | /** | ||
1772 | * snd_pcm_hw_param_near | ||
1773 | * @pcm: PCM instance | ||
1774 | * @params: the hw_params instance | ||
1775 | * @var: parameter to retrieve | ||
1776 | * @best: value to set | ||
1777 | * @dir: pointer to the direction (-1,0,1) or NULL | ||
1778 | * | ||
1779 | * Inside configuration space defined by PARAMS set PAR to the available value | ||
1780 | * nearest to VAL. Reduce configuration space accordingly. | ||
1781 | * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS, | ||
1782 | * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT. | ||
1783 | * Return the value found. | ||
1784 | */ | ||
1785 | int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params, | ||
1786 | snd_pcm_hw_param_t var, unsigned int best, int *dir) | ||
1787 | { | ||
1788 | struct snd_pcm_hw_params *save = NULL; | ||
1789 | int v; | ||
1790 | unsigned int saved_min; | ||
1791 | int last = 0; | ||
1792 | int min, max; | ||
1793 | int mindir, maxdir; | ||
1794 | int valdir = dir ? *dir : 0; | ||
1795 | /* FIXME */ | ||
1796 | if (best > INT_MAX) | ||
1797 | best = INT_MAX; | ||
1798 | min = max = best; | ||
1799 | mindir = maxdir = valdir; | ||
1800 | if (maxdir > 0) | ||
1801 | maxdir = 0; | ||
1802 | else if (maxdir == 0) | ||
1803 | maxdir = -1; | ||
1804 | else { | ||
1805 | maxdir = 1; | ||
1806 | max--; | ||
1807 | } | ||
1808 | save = kmalloc(sizeof(*save), GFP_KERNEL); | ||
1809 | if (save == NULL) | ||
1810 | return -ENOMEM; | ||
1811 | *save = *params; | ||
1812 | saved_min = min; | ||
1813 | min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir); | ||
1814 | if (min >= 0) { | ||
1815 | struct snd_pcm_hw_params *params1; | ||
1816 | if (max < 0) | ||
1817 | goto _end; | ||
1818 | if ((unsigned int)min == saved_min && mindir == valdir) | ||
1819 | goto _end; | ||
1820 | params1 = kmalloc(sizeof(*params1), GFP_KERNEL); | ||
1821 | if (params1 == NULL) { | ||
1822 | kfree(save); | ||
1823 | return -ENOMEM; | ||
1824 | } | ||
1825 | *params1 = *save; | ||
1826 | max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir); | ||
1827 | if (max < 0) { | ||
1828 | kfree(params1); | ||
1829 | goto _end; | ||
1830 | } | ||
1831 | if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) { | ||
1832 | *params = *params1; | ||
1833 | last = 1; | ||
1834 | } | ||
1835 | kfree(params1); | ||
1836 | } else { | ||
1837 | *params = *save; | ||
1838 | max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir); | ||
1839 | assert(max >= 0); | ||
1840 | last = 1; | ||
1841 | } | ||
1842 | _end: | ||
1843 | kfree(save); | ||
1844 | if (last) | ||
1845 | v = snd_pcm_hw_param_last(pcm, params, var, dir); | ||
1846 | else | ||
1847 | v = snd_pcm_hw_param_first(pcm, params, var, dir); | ||
1848 | assert(v >= 0); | ||
1849 | return v; | ||
1850 | } | ||
1851 | 1337 | ||
1852 | /** | 1338 | /** |
1853 | * snd_pcm_hw_param_choose | 1339 | * snd_pcm_hw_param_choose |
@@ -1859,39 +1345,32 @@ int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, struct snd_pcm_hw_param | |||
1859 | * first access, first format, first subformat, min channels, | 1345 | * first access, first format, first subformat, min channels, |
1860 | * min rate, min period time, max buffer size, min tick time | 1346 | * min rate, min period time, max buffer size, min tick time |
1861 | */ | 1347 | */ |
1862 | int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params) | 1348 | int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, |
1863 | { | 1349 | struct snd_pcm_hw_params *params) |
1864 | int err; | 1350 | { |
1865 | 1351 | static int vars[] = { | |
1866 | err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_ACCESS, NULL); | 1352 | SNDRV_PCM_HW_PARAM_ACCESS, |
1867 | assert(err >= 0); | 1353 | SNDRV_PCM_HW_PARAM_FORMAT, |
1868 | 1354 | SNDRV_PCM_HW_PARAM_SUBFORMAT, | |
1869 | err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_FORMAT, NULL); | 1355 | SNDRV_PCM_HW_PARAM_CHANNELS, |
1870 | assert(err >= 0); | 1356 | SNDRV_PCM_HW_PARAM_RATE, |
1871 | 1357 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, | |
1872 | err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_SUBFORMAT, NULL); | 1358 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, |
1873 | assert(err >= 0); | 1359 | SNDRV_PCM_HW_PARAM_TICK_TIME, |
1874 | 1360 | -1 | |
1875 | err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_CHANNELS, NULL); | 1361 | }; |
1876 | assert(err >= 0); | 1362 | int err, *v; |
1877 | |||
1878 | err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_RATE, NULL); | ||
1879 | assert(err >= 0); | ||
1880 | |||
1881 | err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_PERIOD_TIME, NULL); | ||
1882 | assert(err >= 0); | ||
1883 | |||
1884 | err = snd_pcm_hw_param_last(pcm, params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL); | ||
1885 | assert(err >= 0); | ||
1886 | |||
1887 | err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_TICK_TIME, NULL); | ||
1888 | assert(err >= 0); | ||
1889 | 1363 | ||
1364 | for (v = vars; *v != -1; v++) { | ||
1365 | if (*v != SNDRV_PCM_HW_PARAM_BUFFER_SIZE) | ||
1366 | err = snd_pcm_hw_param_first(pcm, params, *v, NULL); | ||
1367 | else | ||
1368 | err = snd_pcm_hw_param_last(pcm, params, *v, NULL); | ||
1369 | snd_assert(err >= 0, return err); | ||
1370 | } | ||
1890 | return 0; | 1371 | return 0; |
1891 | } | 1372 | } |
1892 | 1373 | ||
1893 | #undef assert | ||
1894 | |||
1895 | static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream, | 1374 | static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream, |
1896 | void *arg) | 1375 | void *arg) |
1897 | { | 1376 | { |
@@ -1967,6 +1446,8 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, | |||
1967 | return -ENXIO; | 1446 | return -ENXIO; |
1968 | } | 1447 | } |
1969 | 1448 | ||
1449 | EXPORT_SYMBOL(snd_pcm_lib_ioctl); | ||
1450 | |||
1970 | /* | 1451 | /* |
1971 | * Conditions | 1452 | * Conditions |
1972 | */ | 1453 | */ |
@@ -2101,6 +1582,8 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream) | |||
2101 | kill_fasync(&runtime->fasync, SIGIO, POLL_IN); | 1582 | kill_fasync(&runtime->fasync, SIGIO, POLL_IN); |
2102 | } | 1583 | } |
2103 | 1584 | ||
1585 | EXPORT_SYMBOL(snd_pcm_period_elapsed); | ||
1586 | |||
2104 | static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, | 1587 | static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, |
2105 | unsigned int hwoff, | 1588 | unsigned int hwoff, |
2106 | unsigned long data, unsigned int off, | 1589 | unsigned long data, unsigned int off, |
@@ -2299,7 +1782,7 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v | |||
2299 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | 1782 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
2300 | return -EBADFD; | 1783 | return -EBADFD; |
2301 | 1784 | ||
2302 | nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); | 1785 | nonblock = !!(substream->f_flags & O_NONBLOCK); |
2303 | 1786 | ||
2304 | if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && | 1787 | if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && |
2305 | runtime->channels > 1) | 1788 | runtime->channels > 1) |
@@ -2308,6 +1791,8 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v | |||
2308 | snd_pcm_lib_write_transfer); | 1791 | snd_pcm_lib_write_transfer); |
2309 | } | 1792 | } |
2310 | 1793 | ||
1794 | EXPORT_SYMBOL(snd_pcm_lib_write); | ||
1795 | |||
2311 | static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, | 1796 | static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, |
2312 | unsigned int hwoff, | 1797 | unsigned int hwoff, |
2313 | unsigned long data, unsigned int off, | 1798 | unsigned long data, unsigned int off, |
@@ -2362,7 +1847,7 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream, | |||
2362 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | 1847 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
2363 | return -EBADFD; | 1848 | return -EBADFD; |
2364 | 1849 | ||
2365 | nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); | 1850 | nonblock = !!(substream->f_flags & O_NONBLOCK); |
2366 | 1851 | ||
2367 | if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) | 1852 | if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) |
2368 | return -EINVAL; | 1853 | return -EINVAL; |
@@ -2370,6 +1855,8 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream, | |||
2370 | nonblock, snd_pcm_lib_writev_transfer); | 1855 | nonblock, snd_pcm_lib_writev_transfer); |
2371 | } | 1856 | } |
2372 | 1857 | ||
1858 | EXPORT_SYMBOL(snd_pcm_lib_writev); | ||
1859 | |||
2373 | static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, | 1860 | static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, |
2374 | unsigned int hwoff, | 1861 | unsigned int hwoff, |
2375 | unsigned long data, unsigned int off, | 1862 | unsigned long data, unsigned int off, |
@@ -2572,12 +2059,14 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u | |||
2572 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | 2059 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
2573 | return -EBADFD; | 2060 | return -EBADFD; |
2574 | 2061 | ||
2575 | nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); | 2062 | nonblock = !!(substream->f_flags & O_NONBLOCK); |
2576 | if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) | 2063 | if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) |
2577 | return -EINVAL; | 2064 | return -EINVAL; |
2578 | return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); | 2065 | return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); |
2579 | } | 2066 | } |
2580 | 2067 | ||
2068 | EXPORT_SYMBOL(snd_pcm_lib_read); | ||
2069 | |||
2581 | static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, | 2070 | static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, |
2582 | unsigned int hwoff, | 2071 | unsigned int hwoff, |
2583 | unsigned long data, unsigned int off, | 2072 | unsigned long data, unsigned int off, |
@@ -2629,58 +2118,10 @@ snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream, | |||
2629 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | 2118 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
2630 | return -EBADFD; | 2119 | return -EBADFD; |
2631 | 2120 | ||
2632 | nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); | 2121 | nonblock = !!(substream->f_flags & O_NONBLOCK); |
2633 | if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) | 2122 | if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) |
2634 | return -EINVAL; | 2123 | return -EINVAL; |
2635 | return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer); | 2124 | return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer); |
2636 | } | 2125 | } |
2637 | 2126 | ||
2638 | /* | ||
2639 | * Exported symbols | ||
2640 | */ | ||
2641 | |||
2642 | EXPORT_SYMBOL(snd_interval_refine); | ||
2643 | EXPORT_SYMBOL(snd_interval_list); | ||
2644 | EXPORT_SYMBOL(snd_interval_ratnum); | ||
2645 | EXPORT_SYMBOL(_snd_pcm_hw_params_any); | ||
2646 | EXPORT_SYMBOL(_snd_pcm_hw_param_min); | ||
2647 | EXPORT_SYMBOL(_snd_pcm_hw_param_set); | ||
2648 | EXPORT_SYMBOL(_snd_pcm_hw_param_setempty); | ||
2649 | EXPORT_SYMBOL(_snd_pcm_hw_param_setinteger); | ||
2650 | EXPORT_SYMBOL(snd_pcm_hw_param_value_min); | ||
2651 | EXPORT_SYMBOL(snd_pcm_hw_param_value_max); | ||
2652 | EXPORT_SYMBOL(snd_pcm_hw_param_mask); | ||
2653 | EXPORT_SYMBOL(snd_pcm_hw_param_first); | ||
2654 | EXPORT_SYMBOL(snd_pcm_hw_param_last); | ||
2655 | EXPORT_SYMBOL(snd_pcm_hw_param_near); | ||
2656 | EXPORT_SYMBOL(snd_pcm_hw_param_set); | ||
2657 | EXPORT_SYMBOL(snd_pcm_hw_refine); | ||
2658 | EXPORT_SYMBOL(snd_pcm_hw_constraints_init); | ||
2659 | EXPORT_SYMBOL(snd_pcm_hw_constraints_complete); | ||
2660 | EXPORT_SYMBOL(snd_pcm_hw_constraint_list); | ||
2661 | EXPORT_SYMBOL(snd_pcm_hw_constraint_step); | ||
2662 | EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums); | ||
2663 | EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens); | ||
2664 | EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits); | ||
2665 | EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax); | ||
2666 | EXPORT_SYMBOL(snd_pcm_hw_constraint_integer); | ||
2667 | EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2); | ||
2668 | EXPORT_SYMBOL(snd_pcm_hw_rule_add); | ||
2669 | EXPORT_SYMBOL(snd_pcm_set_ops); | ||
2670 | EXPORT_SYMBOL(snd_pcm_set_sync); | ||
2671 | EXPORT_SYMBOL(snd_pcm_lib_ioctl); | ||
2672 | EXPORT_SYMBOL(snd_pcm_stop); | ||
2673 | EXPORT_SYMBOL(snd_pcm_period_elapsed); | ||
2674 | EXPORT_SYMBOL(snd_pcm_lib_write); | ||
2675 | EXPORT_SYMBOL(snd_pcm_lib_read); | ||
2676 | EXPORT_SYMBOL(snd_pcm_lib_writev); | ||
2677 | EXPORT_SYMBOL(snd_pcm_lib_readv); | 2127 | EXPORT_SYMBOL(snd_pcm_lib_readv); |
2678 | EXPORT_SYMBOL(snd_pcm_lib_buffer_bytes); | ||
2679 | EXPORT_SYMBOL(snd_pcm_lib_period_bytes); | ||
2680 | /* pcm_memory.c */ | ||
2681 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all); | ||
2682 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages); | ||
2683 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all); | ||
2684 | EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page); | ||
2685 | EXPORT_SYMBOL(snd_pcm_lib_malloc_pages); | ||
2686 | EXPORT_SYMBOL(snd_pcm_lib_free_pages); | ||
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index 428f8c169ee1..067d2056db9a 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c | |||
@@ -126,6 +126,8 @@ int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm) | |||
126 | return 0; | 126 | return 0; |
127 | } | 127 | } |
128 | 128 | ||
129 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all); | ||
130 | |||
129 | #ifdef CONFIG_SND_VERBOSE_PROCFS | 131 | #ifdef CONFIG_SND_VERBOSE_PROCFS |
130 | /* | 132 | /* |
131 | * read callback for prealloc proc file | 133 | * read callback for prealloc proc file |
@@ -191,9 +193,7 @@ static inline void preallocate_info_init(struct snd_pcm_substream *substream) | |||
191 | struct snd_info_entry *entry; | 193 | struct snd_info_entry *entry; |
192 | 194 | ||
193 | if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) { | 195 | if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) { |
194 | entry->c.text.read_size = 64; | ||
195 | entry->c.text.read = snd_pcm_lib_preallocate_proc_read; | 196 | entry->c.text.read = snd_pcm_lib_preallocate_proc_read; |
196 | entry->c.text.write_size = 64; | ||
197 | entry->c.text.write = snd_pcm_lib_preallocate_proc_write; | 197 | entry->c.text.write = snd_pcm_lib_preallocate_proc_write; |
198 | entry->mode |= S_IWUSR; | 198 | entry->mode |= S_IWUSR; |
199 | entry->private_data = substream; | 199 | entry->private_data = substream; |
@@ -253,6 +253,8 @@ int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream, | |||
253 | return snd_pcm_lib_preallocate_pages1(substream, size, max); | 253 | return snd_pcm_lib_preallocate_pages1(substream, size, max); |
254 | } | 254 | } |
255 | 255 | ||
256 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages); | ||
257 | |||
256 | /** | 258 | /** |
257 | * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams) | 259 | * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams) |
258 | * @pcm: the pcm instance | 260 | * @pcm: the pcm instance |
@@ -280,6 +282,8 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm, | |||
280 | return 0; | 282 | return 0; |
281 | } | 283 | } |
282 | 284 | ||
285 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all); | ||
286 | |||
283 | /** | 287 | /** |
284 | * snd_pcm_sgbuf_ops_page - get the page struct at the given offset | 288 | * snd_pcm_sgbuf_ops_page - get the page struct at the given offset |
285 | * @substream: the pcm substream instance | 289 | * @substream: the pcm substream instance |
@@ -298,6 +302,8 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne | |||
298 | return sgbuf->page_table[idx]; | 302 | return sgbuf->page_table[idx]; |
299 | } | 303 | } |
300 | 304 | ||
305 | EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page); | ||
306 | |||
301 | /** | 307 | /** |
302 | * snd_pcm_lib_malloc_pages - allocate the DMA buffer | 308 | * snd_pcm_lib_malloc_pages - allocate the DMA buffer |
303 | * @substream: the substream to allocate the DMA buffer to | 309 | * @substream: the substream to allocate the DMA buffer to |
@@ -349,6 +355,8 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size) | |||
349 | return 1; /* area was changed */ | 355 | return 1; /* area was changed */ |
350 | } | 356 | } |
351 | 357 | ||
358 | EXPORT_SYMBOL(snd_pcm_lib_malloc_pages); | ||
359 | |||
352 | /** | 360 | /** |
353 | * snd_pcm_lib_free_pages - release the allocated DMA buffer. | 361 | * snd_pcm_lib_free_pages - release the allocated DMA buffer. |
354 | * @substream: the substream to release the DMA buffer | 362 | * @substream: the substream to release the DMA buffer |
@@ -374,3 +382,5 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream) | |||
374 | snd_pcm_set_runtime_buffer(substream, NULL); | 382 | snd_pcm_set_runtime_buffer(substream, NULL); |
375 | return 0; | 383 | return 0; |
376 | } | 384 | } |
385 | |||
386 | EXPORT_SYMBOL(snd_pcm_lib_free_pages); | ||
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index 593c77f4d181..0019c59a779d 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c | |||
@@ -207,6 +207,8 @@ int snd_pcm_format_signed(snd_pcm_format_t format) | |||
207 | return val; | 207 | return val; |
208 | } | 208 | } |
209 | 209 | ||
210 | EXPORT_SYMBOL(snd_pcm_format_signed); | ||
211 | |||
210 | /** | 212 | /** |
211 | * snd_pcm_format_unsigned - Check the PCM format is unsigned linear | 213 | * snd_pcm_format_unsigned - Check the PCM format is unsigned linear |
212 | * @format: the format to check | 214 | * @format: the format to check |
@@ -224,6 +226,8 @@ int snd_pcm_format_unsigned(snd_pcm_format_t format) | |||
224 | return !val; | 226 | return !val; |
225 | } | 227 | } |
226 | 228 | ||
229 | EXPORT_SYMBOL(snd_pcm_format_unsigned); | ||
230 | |||
227 | /** | 231 | /** |
228 | * snd_pcm_format_linear - Check the PCM format is linear | 232 | * snd_pcm_format_linear - Check the PCM format is linear |
229 | * @format: the format to check | 233 | * @format: the format to check |
@@ -235,6 +239,8 @@ int snd_pcm_format_linear(snd_pcm_format_t format) | |||
235 | return snd_pcm_format_signed(format) >= 0; | 239 | return snd_pcm_format_signed(format) >= 0; |
236 | } | 240 | } |
237 | 241 | ||
242 | EXPORT_SYMBOL(snd_pcm_format_linear); | ||
243 | |||
238 | /** | 244 | /** |
239 | * snd_pcm_format_little_endian - Check the PCM format is little-endian | 245 | * snd_pcm_format_little_endian - Check the PCM format is little-endian |
240 | * @format: the format to check | 246 | * @format: the format to check |
@@ -252,6 +258,8 @@ int snd_pcm_format_little_endian(snd_pcm_format_t format) | |||
252 | return val; | 258 | return val; |
253 | } | 259 | } |
254 | 260 | ||
261 | EXPORT_SYMBOL(snd_pcm_format_little_endian); | ||
262 | |||
255 | /** | 263 | /** |
256 | * snd_pcm_format_big_endian - Check the PCM format is big-endian | 264 | * snd_pcm_format_big_endian - Check the PCM format is big-endian |
257 | * @format: the format to check | 265 | * @format: the format to check |
@@ -269,6 +277,8 @@ int snd_pcm_format_big_endian(snd_pcm_format_t format) | |||
269 | return !val; | 277 | return !val; |
270 | } | 278 | } |
271 | 279 | ||
280 | EXPORT_SYMBOL(snd_pcm_format_big_endian); | ||
281 | |||
272 | /** | 282 | /** |
273 | * snd_pcm_format_width - return the bit-width of the format | 283 | * snd_pcm_format_width - return the bit-width of the format |
274 | * @format: the format to check | 284 | * @format: the format to check |
@@ -286,6 +296,8 @@ int snd_pcm_format_width(snd_pcm_format_t format) | |||
286 | return val; | 296 | return val; |
287 | } | 297 | } |
288 | 298 | ||
299 | EXPORT_SYMBOL(snd_pcm_format_width); | ||
300 | |||
289 | /** | 301 | /** |
290 | * snd_pcm_format_physical_width - return the physical bit-width of the format | 302 | * snd_pcm_format_physical_width - return the physical bit-width of the format |
291 | * @format: the format to check | 303 | * @format: the format to check |
@@ -303,6 +315,8 @@ int snd_pcm_format_physical_width(snd_pcm_format_t format) | |||
303 | return val; | 315 | return val; |
304 | } | 316 | } |
305 | 317 | ||
318 | EXPORT_SYMBOL(snd_pcm_format_physical_width); | ||
319 | |||
306 | /** | 320 | /** |
307 | * snd_pcm_format_size - return the byte size of samples on the given format | 321 | * snd_pcm_format_size - return the byte size of samples on the given format |
308 | * @format: the format to check | 322 | * @format: the format to check |
@@ -318,6 +332,8 @@ ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples) | |||
318 | return samples * phys_width / 8; | 332 | return samples * phys_width / 8; |
319 | } | 333 | } |
320 | 334 | ||
335 | EXPORT_SYMBOL(snd_pcm_format_size); | ||
336 | |||
321 | /** | 337 | /** |
322 | * snd_pcm_format_silence_64 - return the silent data in 8 bytes array | 338 | * snd_pcm_format_silence_64 - return the silent data in 8 bytes array |
323 | * @format: the format to check | 339 | * @format: the format to check |
@@ -333,6 +349,8 @@ const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format) | |||
333 | return pcm_formats[format].silence; | 349 | return pcm_formats[format].silence; |
334 | } | 350 | } |
335 | 351 | ||
352 | EXPORT_SYMBOL(snd_pcm_format_silence_64); | ||
353 | |||
336 | /** | 354 | /** |
337 | * snd_pcm_format_set_silence - set the silence data on the buffer | 355 | * snd_pcm_format_set_silence - set the silence data on the buffer |
338 | * @format: the PCM format | 356 | * @format: the PCM format |
@@ -402,6 +420,8 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int | |||
402 | return 0; | 420 | return 0; |
403 | } | 421 | } |
404 | 422 | ||
423 | EXPORT_SYMBOL(snd_pcm_format_set_silence); | ||
424 | |||
405 | /* [width][unsigned][bigendian] */ | 425 | /* [width][unsigned][bigendian] */ |
406 | static int linear_formats[4][2][2] = { | 426 | static int linear_formats[4][2][2] = { |
407 | {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8}, | 427 | {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8}, |
@@ -432,6 +452,8 @@ snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_end | |||
432 | return linear_formats[width][!!unsignd][!!big_endian]; | 452 | return linear_formats[width][!!unsignd][!!big_endian]; |
433 | } | 453 | } |
434 | 454 | ||
455 | EXPORT_SYMBOL(snd_pcm_build_linear_format); | ||
456 | |||
435 | /** | 457 | /** |
436 | * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields | 458 | * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields |
437 | * @runtime: the runtime instance | 459 | * @runtime: the runtime instance |
@@ -463,3 +485,5 @@ int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime) | |||
463 | } | 485 | } |
464 | return 0; | 486 | return 0; |
465 | } | 487 | } |
488 | |||
489 | EXPORT_SYMBOL(snd_pcm_limit_hw_rates); | ||
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 0860c5a84502..439f047929e1 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -71,8 +71,9 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream); | |||
71 | */ | 71 | */ |
72 | 72 | ||
73 | DEFINE_RWLOCK(snd_pcm_link_rwlock); | 73 | DEFINE_RWLOCK(snd_pcm_link_rwlock); |
74 | static DECLARE_RWSEM(snd_pcm_link_rwsem); | 74 | EXPORT_SYMBOL(snd_pcm_link_rwlock); |
75 | 75 | ||
76 | static DECLARE_RWSEM(snd_pcm_link_rwsem); | ||
76 | 77 | ||
77 | static inline mm_segment_t snd_enter_user(void) | 78 | static inline mm_segment_t snd_enter_user(void) |
78 | { | 79 | { |
@@ -319,6 +320,8 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, | |||
319 | return 0; | 320 | return 0; |
320 | } | 321 | } |
321 | 322 | ||
323 | EXPORT_SYMBOL(snd_pcm_hw_refine); | ||
324 | |||
322 | static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream, | 325 | static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream, |
323 | struct snd_pcm_hw_params __user * _params) | 326 | struct snd_pcm_hw_params __user * _params) |
324 | { | 327 | { |
@@ -369,7 +372,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, | |||
369 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) | 372 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) |
370 | if (!substream->oss.oss) | 373 | if (!substream->oss.oss) |
371 | #endif | 374 | #endif |
372 | if (atomic_read(&runtime->mmap_count)) | 375 | if (atomic_read(&substream->mmap_count)) |
373 | return -EBADFD; | 376 | return -EBADFD; |
374 | 377 | ||
375 | params->rmask = ~0U; | 378 | params->rmask = ~0U; |
@@ -482,7 +485,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) | |||
482 | return -EBADFD; | 485 | return -EBADFD; |
483 | } | 486 | } |
484 | snd_pcm_stream_unlock_irq(substream); | 487 | snd_pcm_stream_unlock_irq(substream); |
485 | if (atomic_read(&runtime->mmap_count)) | 488 | if (atomic_read(&substream->mmap_count)) |
486 | return -EBADFD; | 489 | return -EBADFD; |
487 | if (substream->ops->hw_free) | 490 | if (substream->ops->hw_free) |
488 | result = substream->ops->hw_free(substream); | 491 | result = substream->ops->hw_free(substream); |
@@ -936,6 +939,8 @@ int snd_pcm_stop(struct snd_pcm_substream *substream, int state) | |||
936 | return snd_pcm_action(&snd_pcm_action_stop, substream, state); | 939 | return snd_pcm_action(&snd_pcm_action_stop, substream, state); |
937 | } | 940 | } |
938 | 941 | ||
942 | EXPORT_SYMBOL(snd_pcm_stop); | ||
943 | |||
939 | /** | 944 | /** |
940 | * snd_pcm_drain_done | 945 | * snd_pcm_drain_done |
941 | * @substream: the PCM substream | 946 | * @substream: the PCM substream |
@@ -1085,6 +1090,8 @@ int snd_pcm_suspend(struct snd_pcm_substream *substream) | |||
1085 | return err; | 1090 | return err; |
1086 | } | 1091 | } |
1087 | 1092 | ||
1093 | EXPORT_SYMBOL(snd_pcm_suspend); | ||
1094 | |||
1088 | /** | 1095 | /** |
1089 | * snd_pcm_suspend_all | 1096 | * snd_pcm_suspend_all |
1090 | * @pcm: the PCM instance | 1097 | * @pcm: the PCM instance |
@@ -1114,6 +1121,8 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm) | |||
1114 | return 0; | 1121 | return 0; |
1115 | } | 1122 | } |
1116 | 1123 | ||
1124 | EXPORT_SYMBOL(snd_pcm_suspend_all); | ||
1125 | |||
1117 | /* resume */ | 1126 | /* resume */ |
1118 | 1127 | ||
1119 | static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state) | 1128 | static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state) |
@@ -1275,13 +1284,16 @@ static int snd_pcm_reset(struct snd_pcm_substream *substream) | |||
1275 | /* | 1284 | /* |
1276 | * prepare ioctl | 1285 | * prepare ioctl |
1277 | */ | 1286 | */ |
1278 | static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream, int state) | 1287 | /* we use the second argument for updating f_flags */ |
1288 | static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream, | ||
1289 | int f_flags) | ||
1279 | { | 1290 | { |
1280 | struct snd_pcm_runtime *runtime = substream->runtime; | 1291 | struct snd_pcm_runtime *runtime = substream->runtime; |
1281 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | 1292 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
1282 | return -EBADFD; | 1293 | return -EBADFD; |
1283 | if (snd_pcm_running(substream)) | 1294 | if (snd_pcm_running(substream)) |
1284 | return -EBUSY; | 1295 | return -EBUSY; |
1296 | substream->f_flags = f_flags; | ||
1285 | return 0; | 1297 | return 0; |
1286 | } | 1298 | } |
1287 | 1299 | ||
@@ -1310,17 +1322,26 @@ static struct action_ops snd_pcm_action_prepare = { | |||
1310 | /** | 1322 | /** |
1311 | * snd_pcm_prepare | 1323 | * snd_pcm_prepare |
1312 | * @substream: the PCM substream instance | 1324 | * @substream: the PCM substream instance |
1325 | * @file: file to refer f_flags | ||
1313 | * | 1326 | * |
1314 | * Prepare the PCM substream to be triggerable. | 1327 | * Prepare the PCM substream to be triggerable. |
1315 | */ | 1328 | */ |
1316 | static int snd_pcm_prepare(struct snd_pcm_substream *substream) | 1329 | static int snd_pcm_prepare(struct snd_pcm_substream *substream, |
1330 | struct file *file) | ||
1317 | { | 1331 | { |
1318 | int res; | 1332 | int res; |
1319 | struct snd_card *card = substream->pcm->card; | 1333 | struct snd_card *card = substream->pcm->card; |
1334 | int f_flags; | ||
1335 | |||
1336 | if (file) | ||
1337 | f_flags = file->f_flags; | ||
1338 | else | ||
1339 | f_flags = substream->f_flags; | ||
1320 | 1340 | ||
1321 | snd_power_lock(card); | 1341 | snd_power_lock(card); |
1322 | if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0) | 1342 | if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0) |
1323 | res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare, substream, 0); | 1343 | res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare, |
1344 | substream, f_flags); | ||
1324 | snd_power_unlock(card); | 1345 | snd_power_unlock(card); |
1325 | return res; | 1346 | return res; |
1326 | } | 1347 | } |
@@ -1331,7 +1352,7 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream) | |||
1331 | 1352 | ||
1332 | static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state) | 1353 | static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state) |
1333 | { | 1354 | { |
1334 | if (substream->ffile->f_flags & O_NONBLOCK) | 1355 | if (substream->f_flags & O_NONBLOCK) |
1335 | return -EAGAIN; | 1356 | return -EAGAIN; |
1336 | substream->runtime->trigger_master = substream; | 1357 | substream->runtime->trigger_master = substream; |
1337 | return 0; | 1358 | return 0; |
@@ -1448,8 +1469,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) | |||
1448 | } | 1469 | } |
1449 | } | 1470 | } |
1450 | up_read(&snd_pcm_link_rwsem); | 1471 | up_read(&snd_pcm_link_rwsem); |
1451 | if (! num_drecs) | ||
1452 | goto _error; | ||
1453 | 1472 | ||
1454 | snd_pcm_stream_lock_irq(substream); | 1473 | snd_pcm_stream_lock_irq(substream); |
1455 | /* resume pause */ | 1474 | /* resume pause */ |
@@ -2006,6 +2025,10 @@ static void pcm_release_private(struct snd_pcm_substream *substream) | |||
2006 | 2025 | ||
2007 | void snd_pcm_release_substream(struct snd_pcm_substream *substream) | 2026 | void snd_pcm_release_substream(struct snd_pcm_substream *substream) |
2008 | { | 2027 | { |
2028 | substream->ref_count--; | ||
2029 | if (substream->ref_count > 0) | ||
2030 | return; | ||
2031 | |||
2009 | snd_pcm_drop(substream); | 2032 | snd_pcm_drop(substream); |
2010 | if (substream->hw_opened) { | 2033 | if (substream->hw_opened) { |
2011 | if (substream->ops->hw_free != NULL) | 2034 | if (substream->ops->hw_free != NULL) |
@@ -2020,6 +2043,8 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream) | |||
2020 | snd_pcm_detach_substream(substream); | 2043 | snd_pcm_detach_substream(substream); |
2021 | } | 2044 | } |
2022 | 2045 | ||
2046 | EXPORT_SYMBOL(snd_pcm_release_substream); | ||
2047 | |||
2023 | int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, | 2048 | int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, |
2024 | struct file *file, | 2049 | struct file *file, |
2025 | struct snd_pcm_substream **rsubstream) | 2050 | struct snd_pcm_substream **rsubstream) |
@@ -2030,6 +2055,11 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, | |||
2030 | err = snd_pcm_attach_substream(pcm, stream, file, &substream); | 2055 | err = snd_pcm_attach_substream(pcm, stream, file, &substream); |
2031 | if (err < 0) | 2056 | if (err < 0) |
2032 | return err; | 2057 | return err; |
2058 | if (substream->ref_count > 1) { | ||
2059 | *rsubstream = substream; | ||
2060 | return 0; | ||
2061 | } | ||
2062 | |||
2033 | substream->no_mmap_ctrl = 0; | 2063 | substream->no_mmap_ctrl = 0; |
2034 | err = snd_pcm_hw_constraints_init(substream); | 2064 | err = snd_pcm_hw_constraints_init(substream); |
2035 | if (err < 0) { | 2065 | if (err < 0) { |
@@ -2056,6 +2086,8 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, | |||
2056 | return err; | 2086 | return err; |
2057 | } | 2087 | } |
2058 | 2088 | ||
2089 | EXPORT_SYMBOL(snd_pcm_open_substream); | ||
2090 | |||
2059 | static int snd_pcm_open_file(struct file *file, | 2091 | static int snd_pcm_open_file(struct file *file, |
2060 | struct snd_pcm *pcm, | 2092 | struct snd_pcm *pcm, |
2061 | int stream, | 2093 | int stream, |
@@ -2073,17 +2105,20 @@ static int snd_pcm_open_file(struct file *file, | |||
2073 | if (err < 0) | 2105 | if (err < 0) |
2074 | return err; | 2106 | return err; |
2075 | 2107 | ||
2076 | pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); | 2108 | if (substream->ref_count > 1) |
2077 | if (pcm_file == NULL) { | 2109 | pcm_file = substream->file; |
2078 | snd_pcm_release_substream(substream); | 2110 | else { |
2079 | return -ENOMEM; | 2111 | pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); |
2112 | if (pcm_file == NULL) { | ||
2113 | snd_pcm_release_substream(substream); | ||
2114 | return -ENOMEM; | ||
2115 | } | ||
2116 | str = substream->pstr; | ||
2117 | substream->file = pcm_file; | ||
2118 | substream->pcm_release = pcm_release_private; | ||
2119 | pcm_file->substream = substream; | ||
2120 | snd_pcm_add_file(str, pcm_file); | ||
2080 | } | 2121 | } |
2081 | str = substream->pstr; | ||
2082 | substream->file = pcm_file; | ||
2083 | substream->pcm_release = pcm_release_private; | ||
2084 | pcm_file->substream = substream; | ||
2085 | snd_pcm_add_file(str, pcm_file); | ||
2086 | |||
2087 | file->private_data = pcm_file; | 2122 | file->private_data = pcm_file; |
2088 | *rpcm_file = pcm_file; | 2123 | *rpcm_file = pcm_file; |
2089 | return 0; | 2124 | return 0; |
@@ -2170,7 +2205,6 @@ static int snd_pcm_release(struct inode *inode, struct file *file) | |||
2170 | pcm_file = file->private_data; | 2205 | pcm_file = file->private_data; |
2171 | substream = pcm_file->substream; | 2206 | substream = pcm_file->substream; |
2172 | snd_assert(substream != NULL, return -ENXIO); | 2207 | snd_assert(substream != NULL, return -ENXIO); |
2173 | snd_assert(!atomic_read(&substream->runtime->mmap_count), ); | ||
2174 | pcm = substream->pcm; | 2208 | pcm = substream->pcm; |
2175 | fasync_helper(-1, file, 0, &substream->runtime->fasync); | 2209 | fasync_helper(-1, file, 0, &substream->runtime->fasync); |
2176 | mutex_lock(&pcm->open_mutex); | 2210 | mutex_lock(&pcm->open_mutex); |
@@ -2493,7 +2527,8 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream, | |||
2493 | return 0; | 2527 | return 0; |
2494 | } | 2528 | } |
2495 | 2529 | ||
2496 | static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, | 2530 | static int snd_pcm_common_ioctl1(struct file *file, |
2531 | struct snd_pcm_substream *substream, | ||
2497 | unsigned int cmd, void __user *arg) | 2532 | unsigned int cmd, void __user *arg) |
2498 | { | 2533 | { |
2499 | snd_assert(substream != NULL, return -ENXIO); | 2534 | snd_assert(substream != NULL, return -ENXIO); |
@@ -2518,7 +2553,7 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, | |||
2518 | case SNDRV_PCM_IOCTL_CHANNEL_INFO: | 2553 | case SNDRV_PCM_IOCTL_CHANNEL_INFO: |
2519 | return snd_pcm_channel_info_user(substream, arg); | 2554 | return snd_pcm_channel_info_user(substream, arg); |
2520 | case SNDRV_PCM_IOCTL_PREPARE: | 2555 | case SNDRV_PCM_IOCTL_PREPARE: |
2521 | return snd_pcm_prepare(substream); | 2556 | return snd_pcm_prepare(substream, file); |
2522 | case SNDRV_PCM_IOCTL_RESET: | 2557 | case SNDRV_PCM_IOCTL_RESET: |
2523 | return snd_pcm_reset(substream); | 2558 | return snd_pcm_reset(substream); |
2524 | case SNDRV_PCM_IOCTL_START: | 2559 | case SNDRV_PCM_IOCTL_START: |
@@ -2560,7 +2595,8 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, | |||
2560 | return -ENOTTY; | 2595 | return -ENOTTY; |
2561 | } | 2596 | } |
2562 | 2597 | ||
2563 | static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream, | 2598 | static int snd_pcm_playback_ioctl1(struct file *file, |
2599 | struct snd_pcm_substream *substream, | ||
2564 | unsigned int cmd, void __user *arg) | 2600 | unsigned int cmd, void __user *arg) |
2565 | { | 2601 | { |
2566 | snd_assert(substream != NULL, return -ENXIO); | 2602 | snd_assert(substream != NULL, return -ENXIO); |
@@ -2636,10 +2672,11 @@ static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream, | |||
2636 | return result < 0 ? result : 0; | 2672 | return result < 0 ? result : 0; |
2637 | } | 2673 | } |
2638 | } | 2674 | } |
2639 | return snd_pcm_common_ioctl1(substream, cmd, arg); | 2675 | return snd_pcm_common_ioctl1(file, substream, cmd, arg); |
2640 | } | 2676 | } |
2641 | 2677 | ||
2642 | static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream, | 2678 | static int snd_pcm_capture_ioctl1(struct file *file, |
2679 | struct snd_pcm_substream *substream, | ||
2643 | unsigned int cmd, void __user *arg) | 2680 | unsigned int cmd, void __user *arg) |
2644 | { | 2681 | { |
2645 | snd_assert(substream != NULL, return -ENXIO); | 2682 | snd_assert(substream != NULL, return -ENXIO); |
@@ -2715,7 +2752,7 @@ static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream, | |||
2715 | return result < 0 ? result : 0; | 2752 | return result < 0 ? result : 0; |
2716 | } | 2753 | } |
2717 | } | 2754 | } |
2718 | return snd_pcm_common_ioctl1(substream, cmd, arg); | 2755 | return snd_pcm_common_ioctl1(file, substream, cmd, arg); |
2719 | } | 2756 | } |
2720 | 2757 | ||
2721 | static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd, | 2758 | static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd, |
@@ -2728,7 +2765,8 @@ static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd, | |||
2728 | if (((cmd >> 8) & 0xff) != 'A') | 2765 | if (((cmd >> 8) & 0xff) != 'A') |
2729 | return -ENOTTY; | 2766 | return -ENOTTY; |
2730 | 2767 | ||
2731 | return snd_pcm_playback_ioctl1(pcm_file->substream, cmd, (void __user *)arg); | 2768 | return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd, |
2769 | (void __user *)arg); | ||
2732 | } | 2770 | } |
2733 | 2771 | ||
2734 | static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, | 2772 | static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, |
@@ -2741,7 +2779,8 @@ static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, | |||
2741 | if (((cmd >> 8) & 0xff) != 'A') | 2779 | if (((cmd >> 8) & 0xff) != 'A') |
2742 | return -ENOTTY; | 2780 | return -ENOTTY; |
2743 | 2781 | ||
2744 | return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg); | 2782 | return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd, |
2783 | (void __user *)arg); | ||
2745 | } | 2784 | } |
2746 | 2785 | ||
2747 | int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, | 2786 | int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, |
@@ -2753,12 +2792,12 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, | |||
2753 | fs = snd_enter_user(); | 2792 | fs = snd_enter_user(); |
2754 | switch (substream->stream) { | 2793 | switch (substream->stream) { |
2755 | case SNDRV_PCM_STREAM_PLAYBACK: | 2794 | case SNDRV_PCM_STREAM_PLAYBACK: |
2756 | result = snd_pcm_playback_ioctl1(substream, | 2795 | result = snd_pcm_playback_ioctl1(NULL, substream, cmd, |
2757 | cmd, (void __user *)arg); | 2796 | (void __user *)arg); |
2758 | break; | 2797 | break; |
2759 | case SNDRV_PCM_STREAM_CAPTURE: | 2798 | case SNDRV_PCM_STREAM_CAPTURE: |
2760 | result = snd_pcm_capture_ioctl1(substream, | 2799 | result = snd_pcm_capture_ioctl1(NULL, substream, cmd, |
2761 | cmd, (void __user *)arg); | 2800 | (void __user *)arg); |
2762 | break; | 2801 | break; |
2763 | default: | 2802 | default: |
2764 | result = -EINVAL; | 2803 | result = -EINVAL; |
@@ -2768,6 +2807,8 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, | |||
2768 | return result; | 2807 | return result; |
2769 | } | 2808 | } |
2770 | 2809 | ||
2810 | EXPORT_SYMBOL(snd_pcm_kernel_ioctl); | ||
2811 | |||
2771 | static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, | 2812 | static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, |
2772 | loff_t * offset) | 2813 | loff_t * offset) |
2773 | { | 2814 | { |
@@ -3134,7 +3175,7 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, | |||
3134 | area->vm_ops = &snd_pcm_vm_ops_data; | 3175 | area->vm_ops = &snd_pcm_vm_ops_data; |
3135 | area->vm_private_data = substream; | 3176 | area->vm_private_data = substream; |
3136 | area->vm_flags |= VM_RESERVED; | 3177 | area->vm_flags |= VM_RESERVED; |
3137 | atomic_inc(&substream->runtime->mmap_count); | 3178 | atomic_inc(&substream->mmap_count); |
3138 | return 0; | 3179 | return 0; |
3139 | } | 3180 | } |
3140 | 3181 | ||
@@ -3166,9 +3207,11 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, | |||
3166 | (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, | 3207 | (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, |
3167 | size, area->vm_page_prot)) | 3208 | size, area->vm_page_prot)) |
3168 | return -EAGAIN; | 3209 | return -EAGAIN; |
3169 | atomic_inc(&substream->runtime->mmap_count); | 3210 | atomic_inc(&substream->mmap_count); |
3170 | return 0; | 3211 | return 0; |
3171 | } | 3212 | } |
3213 | |||
3214 | EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); | ||
3172 | #endif /* SNDRV_PCM_INFO_MMAP */ | 3215 | #endif /* SNDRV_PCM_INFO_MMAP */ |
3173 | 3216 | ||
3174 | /* | 3217 | /* |
@@ -3212,6 +3255,8 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, | |||
3212 | return snd_pcm_default_mmap(substream, area); | 3255 | return snd_pcm_default_mmap(substream, area); |
3213 | } | 3256 | } |
3214 | 3257 | ||
3258 | EXPORT_SYMBOL(snd_pcm_mmap_data); | ||
3259 | |||
3215 | static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) | 3260 | static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) |
3216 | { | 3261 | { |
3217 | struct snd_pcm_file * pcm_file; | 3262 | struct snd_pcm_file * pcm_file; |
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 87b47c9564f7..8c15c66eb4aa 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c | |||
@@ -43,7 +43,7 @@ MODULE_DESCRIPTION("Midlevel RawMidi code for ALSA."); | |||
43 | MODULE_LICENSE("GPL"); | 43 | MODULE_LICENSE("GPL"); |
44 | 44 | ||
45 | #ifdef CONFIG_SND_OSSEMUL | 45 | #ifdef CONFIG_SND_OSSEMUL |
46 | static int midi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0}; | 46 | static int midi_map[SNDRV_CARDS]; |
47 | static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; | 47 | static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; |
48 | module_param_array(midi_map, int, NULL, 0444); | 48 | module_param_array(midi_map, int, NULL, 0444); |
49 | MODULE_PARM_DESC(midi_map, "Raw MIDI device number assigned to 1st OSS device."); | 49 | MODULE_PARM_DESC(midi_map, "Raw MIDI device number assigned to 1st OSS device."); |
@@ -1561,7 +1561,6 @@ static int snd_rawmidi_dev_register(struct snd_device *device) | |||
1561 | entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); | 1561 | entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); |
1562 | if (entry) { | 1562 | if (entry) { |
1563 | entry->private_data = rmidi; | 1563 | entry->private_data = rmidi; |
1564 | entry->c.text.read_size = 1024; | ||
1565 | entry->c.text.read = snd_rawmidi_proc_info_read; | 1564 | entry->c.text.read = snd_rawmidi_proc_info_read; |
1566 | if (snd_info_register(entry) < 0) { | 1565 | if (snd_info_register(entry) < 0) { |
1567 | snd_info_free_entry(entry); | 1566 | snd_info_free_entry(entry); |
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c index b9919785180b..e7234135641c 100644 --- a/sound/core/seq/oss/seq_oss.c +++ b/sound/core/seq/oss/seq_oss.c | |||
@@ -291,7 +291,6 @@ register_proc(void) | |||
291 | 291 | ||
292 | entry->content = SNDRV_INFO_CONTENT_TEXT; | 292 | entry->content = SNDRV_INFO_CONTENT_TEXT; |
293 | entry->private_data = NULL; | 293 | entry->private_data = NULL; |
294 | entry->c.text.read_size = 1024; | ||
295 | entry->c.text.read = info_read; | 294 | entry->c.text.read = info_read; |
296 | if (snd_info_register(entry) < 0) { | 295 | if (snd_info_register(entry) < 0) { |
297 | snd_info_free_entry(entry); | 296 | snd_info_free_entry(entry); |
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c index 20f954bc7aa0..2f0d8773ac6b 100644 --- a/sound/core/seq/seq.c +++ b/sound/core/seq/seq.c | |||
@@ -129,25 +129,3 @@ static void __exit alsa_seq_exit(void) | |||
129 | 129 | ||
130 | module_init(alsa_seq_init) | 130 | module_init(alsa_seq_init) |
131 | module_exit(alsa_seq_exit) | 131 | module_exit(alsa_seq_exit) |
132 | |||
133 | /* seq_clientmgr.c */ | ||
134 | EXPORT_SYMBOL(snd_seq_create_kernel_client); | ||
135 | EXPORT_SYMBOL(snd_seq_delete_kernel_client); | ||
136 | EXPORT_SYMBOL(snd_seq_kernel_client_enqueue); | ||
137 | EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking); | ||
138 | EXPORT_SYMBOL(snd_seq_kernel_client_dispatch); | ||
139 | EXPORT_SYMBOL(snd_seq_kernel_client_ctl); | ||
140 | EXPORT_SYMBOL(snd_seq_kernel_client_write_poll); | ||
141 | EXPORT_SYMBOL(snd_seq_set_queue_tempo); | ||
142 | /* seq_memory.c */ | ||
143 | EXPORT_SYMBOL(snd_seq_expand_var_event); | ||
144 | EXPORT_SYMBOL(snd_seq_dump_var_event); | ||
145 | /* seq_ports.c */ | ||
146 | EXPORT_SYMBOL(snd_seq_event_port_attach); | ||
147 | EXPORT_SYMBOL(snd_seq_event_port_detach); | ||
148 | /* seq_lock.c */ | ||
149 | #if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG) | ||
150 | /*EXPORT_SYMBOL(snd_seq_sleep_in_lock);*/ | ||
151 | /*EXPORT_SYMBOL(snd_seq_sleep_timeout_in_lock);*/ | ||
152 | EXPORT_SYMBOL(snd_use_lock_sync_helper); | ||
153 | #endif | ||
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index bb15d9ee8842..532a660df51d 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c | |||
@@ -1714,6 +1714,8 @@ int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo) | |||
1714 | return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo); | 1714 | return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo); |
1715 | } | 1715 | } |
1716 | 1716 | ||
1717 | EXPORT_SYMBOL(snd_seq_set_queue_tempo); | ||
1718 | |||
1717 | static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client, | 1719 | static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client, |
1718 | void __user *arg) | 1720 | void __user *arg) |
1719 | { | 1721 | { |
@@ -2264,6 +2266,8 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, | |||
2264 | return client->number; | 2266 | return client->number; |
2265 | } | 2267 | } |
2266 | 2268 | ||
2269 | EXPORT_SYMBOL(snd_seq_create_kernel_client); | ||
2270 | |||
2267 | /* exported to kernel modules */ | 2271 | /* exported to kernel modules */ |
2268 | int snd_seq_delete_kernel_client(int client) | 2272 | int snd_seq_delete_kernel_client(int client) |
2269 | { | 2273 | { |
@@ -2280,6 +2284,7 @@ int snd_seq_delete_kernel_client(int client) | |||
2280 | return 0; | 2284 | return 0; |
2281 | } | 2285 | } |
2282 | 2286 | ||
2287 | EXPORT_SYMBOL(snd_seq_delete_kernel_client); | ||
2283 | 2288 | ||
2284 | /* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue | 2289 | /* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue |
2285 | * and snd_seq_kernel_client_enqueue_blocking | 2290 | * and snd_seq_kernel_client_enqueue_blocking |
@@ -2328,6 +2333,8 @@ int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event * ev, | |||
2328 | return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop); | 2333 | return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop); |
2329 | } | 2334 | } |
2330 | 2335 | ||
2336 | EXPORT_SYMBOL(snd_seq_kernel_client_enqueue); | ||
2337 | |||
2331 | /* | 2338 | /* |
2332 | * exported, called by kernel clients to enqueue events (with blocking) | 2339 | * exported, called by kernel clients to enqueue events (with blocking) |
2333 | * | 2340 | * |
@@ -2340,6 +2347,7 @@ int snd_seq_kernel_client_enqueue_blocking(int client, struct snd_seq_event * ev | |||
2340 | return kernel_client_enqueue(client, ev, file, 1, atomic, hop); | 2347 | return kernel_client_enqueue(client, ev, file, 1, atomic, hop); |
2341 | } | 2348 | } |
2342 | 2349 | ||
2350 | EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking); | ||
2343 | 2351 | ||
2344 | /* | 2352 | /* |
2345 | * exported, called by kernel clients to dispatch events directly to other | 2353 | * exported, called by kernel clients to dispatch events directly to other |
@@ -2376,6 +2384,7 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev, | |||
2376 | return result; | 2384 | return result; |
2377 | } | 2385 | } |
2378 | 2386 | ||
2387 | EXPORT_SYMBOL(snd_seq_kernel_client_dispatch); | ||
2379 | 2388 | ||
2380 | /* | 2389 | /* |
2381 | * exported, called by kernel clients to perform same functions as with | 2390 | * exported, called by kernel clients to perform same functions as with |
@@ -2396,6 +2405,7 @@ int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg) | |||
2396 | return result; | 2405 | return result; |
2397 | } | 2406 | } |
2398 | 2407 | ||
2408 | EXPORT_SYMBOL(snd_seq_kernel_client_ctl); | ||
2399 | 2409 | ||
2400 | /* exported (for OSS emulator) */ | 2410 | /* exported (for OSS emulator) */ |
2401 | int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait) | 2411 | int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait) |
@@ -2413,6 +2423,8 @@ int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table | |||
2413 | return 0; | 2423 | return 0; |
2414 | } | 2424 | } |
2415 | 2425 | ||
2426 | EXPORT_SYMBOL(snd_seq_kernel_client_write_poll); | ||
2427 | |||
2416 | /*---------------------------------------------------------------------------*/ | 2428 | /*---------------------------------------------------------------------------*/ |
2417 | 2429 | ||
2418 | #ifdef CONFIG_PROC_FS | 2430 | #ifdef CONFIG_PROC_FS |
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index d9a3e5a18d6a..d812dc886360 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c | |||
@@ -80,7 +80,7 @@ static LIST_HEAD(opslist); | |||
80 | static int num_ops; | 80 | static int num_ops; |
81 | static DEFINE_MUTEX(ops_mutex); | 81 | static DEFINE_MUTEX(ops_mutex); |
82 | #ifdef CONFIG_PROC_FS | 82 | #ifdef CONFIG_PROC_FS |
83 | static struct snd_info_entry *info_entry = NULL; | 83 | static struct snd_info_entry *info_entry; |
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | /* | 86 | /* |
@@ -555,7 +555,6 @@ static int __init alsa_seq_device_init(void) | |||
555 | if (info_entry == NULL) | 555 | if (info_entry == NULL) |
556 | return -ENOMEM; | 556 | return -ENOMEM; |
557 | info_entry->content = SNDRV_INFO_CONTENT_TEXT; | 557 | info_entry->content = SNDRV_INFO_CONTENT_TEXT; |
558 | info_entry->c.text.read_size = 2048; | ||
559 | info_entry->c.text.read = snd_seq_device_info; | 558 | info_entry->c.text.read = snd_seq_device_info; |
560 | if (snd_info_register(info_entry) < 0) { | 559 | if (snd_info_register(info_entry) < 0) { |
561 | snd_info_free_entry(info_entry); | 560 | snd_info_free_entry(info_entry); |
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c index 2a283a59ea4d..e55488d1237c 100644 --- a/sound/core/seq/seq_dummy.c +++ b/sound/core/seq/seq_dummy.c | |||
@@ -66,7 +66,7 @@ MODULE_LICENSE("GPL"); | |||
66 | MODULE_ALIAS("snd-seq-client-" __stringify(SNDRV_SEQ_CLIENT_DUMMY)); | 66 | MODULE_ALIAS("snd-seq-client-" __stringify(SNDRV_SEQ_CLIENT_DUMMY)); |
67 | 67 | ||
68 | static int ports = 1; | 68 | static int ports = 1; |
69 | static int duplex = 0; | 69 | static int duplex; |
70 | 70 | ||
71 | module_param(ports, int, 0444); | 71 | module_param(ports, int, 0444); |
72 | MODULE_PARM_DESC(ports, "number of ports to be created"); | 72 | MODULE_PARM_DESC(ports, "number of ports to be created"); |
@@ -171,7 +171,9 @@ create_port(int idx, int type) | |||
171 | pinfo.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; | 171 | pinfo.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; |
172 | if (duplex) | 172 | if (duplex) |
173 | pinfo.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; | 173 | pinfo.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; |
174 | pinfo.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; | 174 | pinfo.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
175 | | SNDRV_SEQ_PORT_TYPE_SOFTWARE | ||
176 | | SNDRV_SEQ_PORT_TYPE_PORT; | ||
175 | memset(&pcb, 0, sizeof(pcb)); | 177 | memset(&pcb, 0, sizeof(pcb)); |
176 | pcb.owner = THIS_MODULE; | 178 | pcb.owner = THIS_MODULE; |
177 | pcb.unuse = dummy_unuse; | 179 | pcb.unuse = dummy_unuse; |
diff --git a/sound/core/seq/seq_info.c b/sound/core/seq/seq_info.c index acce21afdaa4..142e9e6882c9 100644 --- a/sound/core/seq/seq_info.c +++ b/sound/core/seq/seq_info.c | |||
@@ -34,8 +34,8 @@ static struct snd_info_entry *timer_entry; | |||
34 | 34 | ||
35 | 35 | ||
36 | static struct snd_info_entry * __init | 36 | static struct snd_info_entry * __init |
37 | create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *, | 37 | create_info_entry(char *name, void (*read)(struct snd_info_entry *, |
38 | struct snd_info_buffer *)) | 38 | struct snd_info_buffer *)) |
39 | { | 39 | { |
40 | struct snd_info_entry *entry; | 40 | struct snd_info_entry *entry; |
41 | 41 | ||
@@ -43,7 +43,6 @@ create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *, | |||
43 | if (entry == NULL) | 43 | if (entry == NULL) |
44 | return NULL; | 44 | return NULL; |
45 | entry->content = SNDRV_INFO_CONTENT_TEXT; | 45 | entry->content = SNDRV_INFO_CONTENT_TEXT; |
46 | entry->c.text.read_size = size; | ||
47 | entry->c.text.read = read; | 46 | entry->c.text.read = read; |
48 | if (snd_info_register(entry) < 0) { | 47 | if (snd_info_register(entry) < 0) { |
49 | snd_info_free_entry(entry); | 48 | snd_info_free_entry(entry); |
@@ -55,11 +54,11 @@ create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *, | |||
55 | /* create all our /proc entries */ | 54 | /* create all our /proc entries */ |
56 | int __init snd_seq_info_init(void) | 55 | int __init snd_seq_info_init(void) |
57 | { | 56 | { |
58 | queues_entry = create_info_entry("queues", 512 + (256 * SNDRV_SEQ_MAX_QUEUES), | 57 | queues_entry = create_info_entry("queues", |
59 | snd_seq_info_queues_read); | 58 | snd_seq_info_queues_read); |
60 | clients_entry = create_info_entry("clients", 512 + (256 * SNDRV_SEQ_MAX_CLIENTS), | 59 | clients_entry = create_info_entry("clients", |
61 | snd_seq_info_clients_read); | 60 | snd_seq_info_clients_read); |
62 | timer_entry = create_info_entry("timer", 1024, snd_seq_info_timer_read); | 61 | timer_entry = create_info_entry("timer", snd_seq_info_timer_read); |
63 | return 0; | 62 | return 0; |
64 | } | 63 | } |
65 | 64 | ||
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c index a837a94b2d2a..1a34941d4217 100644 --- a/sound/core/seq/seq_lock.c +++ b/sound/core/seq/seq_lock.c | |||
@@ -44,4 +44,6 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) | |||
44 | } | 44 | } |
45 | } | 45 | } |
46 | 46 | ||
47 | EXPORT_SYMBOL(snd_use_lock_sync_helper); | ||
48 | |||
47 | #endif | 49 | #endif |
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index 40b4f679c80e..4bffe509f719 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c | |||
@@ -118,6 +118,8 @@ int snd_seq_dump_var_event(const struct snd_seq_event *event, | |||
118 | return 0; | 118 | return 0; |
119 | } | 119 | } |
120 | 120 | ||
121 | EXPORT_SYMBOL(snd_seq_dump_var_event); | ||
122 | |||
121 | 123 | ||
122 | /* | 124 | /* |
123 | * exported: | 125 | * exported: |
@@ -167,6 +169,7 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char | |||
167 | return err < 0 ? err : newlen; | 169 | return err < 0 ? err : newlen; |
168 | } | 170 | } |
169 | 171 | ||
172 | EXPORT_SYMBOL(snd_seq_expand_var_event); | ||
170 | 173 | ||
171 | /* | 174 | /* |
172 | * release this cell, free extended data if available | 175 | * release this cell, free extended data if available |
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index 9caa1372bece..1daa5b069c79 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c | |||
@@ -278,6 +278,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) | |||
278 | struct seq_midisynth *msynth, *ms; | 278 | struct seq_midisynth *msynth, *ms; |
279 | struct snd_seq_port_info *port; | 279 | struct snd_seq_port_info *port; |
280 | struct snd_rawmidi_info *info; | 280 | struct snd_rawmidi_info *info; |
281 | struct snd_rawmidi *rmidi = dev->private_data; | ||
281 | int newclient = 0; | 282 | int newclient = 0; |
282 | unsigned int p, ports; | 283 | unsigned int p, ports; |
283 | struct snd_seq_port_callback pcallbacks; | 284 | struct snd_seq_port_callback pcallbacks; |
@@ -320,8 +321,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) | |||
320 | } | 321 | } |
321 | client->seq_client = | 322 | client->seq_client = |
322 | snd_seq_create_kernel_client( | 323 | snd_seq_create_kernel_client( |
323 | card, 0, "%s", info->name[0] ? | 324 | card, 0, "%s", card->shortname[0] ? |
324 | (const char *)info->name : "External MIDI"); | 325 | (const char *)card->shortname : "External MIDI"); |
325 | if (client->seq_client < 0) { | 326 | if (client->seq_client < 0) { |
326 | kfree(client); | 327 | kfree(client); |
327 | mutex_unlock(®ister_mutex); | 328 | mutex_unlock(®ister_mutex); |
@@ -376,7 +377,9 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) | |||
376 | if ((port->capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) && | 377 | if ((port->capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) && |
377 | info->flags & SNDRV_RAWMIDI_INFO_DUPLEX) | 378 | info->flags & SNDRV_RAWMIDI_INFO_DUPLEX) |
378 | port->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; | 379 | port->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; |
379 | port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; | 380 | port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
381 | | SNDRV_SEQ_PORT_TYPE_HARDWARE | ||
382 | | SNDRV_SEQ_PORT_TYPE_PORT; | ||
380 | port->midi_channels = 16; | 383 | port->midi_channels = 16; |
381 | memset(&pcallbacks, 0, sizeof(pcallbacks)); | 384 | memset(&pcallbacks, 0, sizeof(pcallbacks)); |
382 | pcallbacks.owner = THIS_MODULE; | 385 | pcallbacks.owner = THIS_MODULE; |
@@ -387,6 +390,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) | |||
387 | pcallbacks.unuse = midisynth_unuse; | 390 | pcallbacks.unuse = midisynth_unuse; |
388 | pcallbacks.event_input = event_process_midi; | 391 | pcallbacks.event_input = event_process_midi; |
389 | port->kernel = &pcallbacks; | 392 | port->kernel = &pcallbacks; |
393 | if (rmidi->ops && rmidi->ops->get_port_info) | ||
394 | rmidi->ops->get_port_info(rmidi, p, port); | ||
390 | if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, port)<0) | 395 | if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, port)<0) |
391 | goto __nomem; | 396 | goto __nomem; |
392 | ms->seq_client = client->seq_client; | 397 | ms->seq_client = client->seq_client; |
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index 41e078c938cd..334579a9f268 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c | |||
@@ -221,7 +221,6 @@ static void clear_subscriber_list(struct snd_seq_client *client, | |||
221 | { | 221 | { |
222 | struct list_head *p, *n; | 222 | struct list_head *p, *n; |
223 | 223 | ||
224 | down_write(&grp->list_mutex); | ||
225 | list_for_each_safe(p, n, &grp->list_head) { | 224 | list_for_each_safe(p, n, &grp->list_head) { |
226 | struct snd_seq_subscribers *subs; | 225 | struct snd_seq_subscribers *subs; |
227 | struct snd_seq_client *c; | 226 | struct snd_seq_client *c; |
@@ -259,7 +258,6 @@ static void clear_subscriber_list(struct snd_seq_client *client, | |||
259 | snd_seq_client_unlock(c); | 258 | snd_seq_client_unlock(c); |
260 | } | 259 | } |
261 | } | 260 | } |
262 | up_write(&grp->list_mutex); | ||
263 | } | 261 | } |
264 | 262 | ||
265 | /* delete port data */ | 263 | /* delete port data */ |
@@ -677,6 +675,7 @@ int snd_seq_event_port_attach(int client, | |||
677 | return ret; | 675 | return ret; |
678 | } | 676 | } |
679 | 677 | ||
678 | EXPORT_SYMBOL(snd_seq_event_port_attach); | ||
680 | 679 | ||
681 | /* | 680 | /* |
682 | * Detach the driver from a port. | 681 | * Detach the driver from a port. |
@@ -696,3 +695,5 @@ int snd_seq_event_port_detach(int client, int port) | |||
696 | 695 | ||
697 | return err; | 696 | return err; |
698 | } | 697 | } |
698 | |||
699 | EXPORT_SYMBOL(snd_seq_event_port_detach); | ||
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index f4edec603b8f..0cfa06c6b81f 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c | |||
@@ -390,7 +390,9 @@ static int snd_virmidi_dev_attach_seq(struct snd_virmidi_dev *rdev) | |||
390 | pinfo->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; | 390 | pinfo->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; |
391 | pinfo->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ; | 391 | pinfo->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ; |
392 | pinfo->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; | 392 | pinfo->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; |
393 | pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; | 393 | pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
394 | | SNDRV_SEQ_PORT_TYPE_SOFTWARE | ||
395 | | SNDRV_SEQ_PORT_TYPE_PORT; | ||
394 | pinfo->midi_channels = 16; | 396 | pinfo->midi_channels = 16; |
395 | memset(&pcallbacks, 0, sizeof(pcallbacks)); | 397 | memset(&pcallbacks, 0, sizeof(pcallbacks)); |
396 | pcallbacks.owner = THIS_MODULE; | 398 | pcallbacks.owner = THIS_MODULE; |
diff --git a/sound/core/sound.c b/sound/core/sound.c index 108e430b5036..cd862728346c 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c | |||
@@ -39,6 +39,8 @@ | |||
39 | 39 | ||
40 | static int major = CONFIG_SND_MAJOR; | 40 | static int major = CONFIG_SND_MAJOR; |
41 | int snd_major; | 41 | int snd_major; |
42 | EXPORT_SYMBOL(snd_major); | ||
43 | |||
42 | static int cards_limit = 1; | 44 | static int cards_limit = 1; |
43 | static int device_mode = S_IFCHR | S_IRUGO | S_IWUGO; | 45 | static int device_mode = S_IFCHR | S_IRUGO | S_IWUGO; |
44 | 46 | ||
@@ -60,6 +62,7 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR); | |||
60 | * modules are loaded manually, this limit number increases, too. | 62 | * modules are loaded manually, this limit number increases, too. |
61 | */ | 63 | */ |
62 | int snd_ecards_limit; | 64 | int snd_ecards_limit; |
65 | EXPORT_SYMBOL(snd_ecards_limit); | ||
63 | 66 | ||
64 | static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; | 67 | static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; |
65 | static DEFINE_MUTEX(sound_mutex); | 68 | static DEFINE_MUTEX(sound_mutex); |
@@ -78,20 +81,17 @@ extern struct class *sound_class; | |||
78 | */ | 81 | */ |
79 | void snd_request_card(int card) | 82 | void snd_request_card(int card) |
80 | { | 83 | { |
81 | int locked; | ||
82 | |||
83 | if (! current->fs->root) | 84 | if (! current->fs->root) |
84 | return; | 85 | return; |
85 | read_lock(&snd_card_rwlock); | 86 | if (snd_card_locked(card)) |
86 | locked = snd_cards_lock & (1 << card); | ||
87 | read_unlock(&snd_card_rwlock); | ||
88 | if (locked) | ||
89 | return; | 87 | return; |
90 | if (card < 0 || card >= cards_limit) | 88 | if (card < 0 || card >= cards_limit) |
91 | return; | 89 | return; |
92 | request_module("snd-card-%i", card); | 90 | request_module("snd-card-%i", card); |
93 | } | 91 | } |
94 | 92 | ||
93 | EXPORT_SYMBOL(snd_request_card); | ||
94 | |||
95 | static void snd_request_other(int minor) | 95 | static void snd_request_other(int minor) |
96 | { | 96 | { |
97 | char *str; | 97 | char *str; |
@@ -133,6 +133,8 @@ void *snd_lookup_minor_data(unsigned int minor, int type) | |||
133 | return private_data; | 133 | return private_data; |
134 | } | 134 | } |
135 | 135 | ||
136 | EXPORT_SYMBOL(snd_lookup_minor_data); | ||
137 | |||
136 | static int snd_open(struct inode *inode, struct file *file) | 138 | static int snd_open(struct inode *inode, struct file *file) |
137 | { | 139 | { |
138 | unsigned int minor = iminor(inode); | 140 | unsigned int minor = iminor(inode); |
@@ -281,6 +283,8 @@ int snd_register_device(int type, struct snd_card *card, int dev, | |||
281 | return 0; | 283 | return 0; |
282 | } | 284 | } |
283 | 285 | ||
286 | EXPORT_SYMBOL(snd_register_device); | ||
287 | |||
284 | /** | 288 | /** |
285 | * snd_unregister_device - unregister the device on the given card | 289 | * snd_unregister_device - unregister the device on the given card |
286 | * @type: the device type, SNDRV_DEVICE_TYPE_XXX | 290 | * @type: the device type, SNDRV_DEVICE_TYPE_XXX |
@@ -321,12 +325,14 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) | |||
321 | return 0; | 325 | return 0; |
322 | } | 326 | } |
323 | 327 | ||
328 | EXPORT_SYMBOL(snd_unregister_device); | ||
329 | |||
324 | #ifdef CONFIG_PROC_FS | 330 | #ifdef CONFIG_PROC_FS |
325 | /* | 331 | /* |
326 | * INFO PART | 332 | * INFO PART |
327 | */ | 333 | */ |
328 | 334 | ||
329 | static struct snd_info_entry *snd_minor_info_entry = NULL; | 335 | static struct snd_info_entry *snd_minor_info_entry; |
330 | 336 | ||
331 | static const char *snd_device_type_name(int type) | 337 | static const char *snd_device_type_name(int type) |
332 | { | 338 | { |
@@ -381,7 +387,6 @@ int __init snd_minor_info_init(void) | |||
381 | 387 | ||
382 | entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL); | 388 | entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL); |
383 | if (entry) { | 389 | if (entry) { |
384 | entry->c.text.read_size = PAGE_SIZE; | ||
385 | entry->c.text.read = snd_minor_info_read; | 390 | entry->c.text.read = snd_minor_info_read; |
386 | if (snd_info_register(entry) < 0) { | 391 | if (snd_info_register(entry) < 0) { |
387 | snd_info_free_entry(entry); | 392 | snd_info_free_entry(entry); |
@@ -446,91 +451,3 @@ static void __exit alsa_sound_exit(void) | |||
446 | 451 | ||
447 | module_init(alsa_sound_init) | 452 | module_init(alsa_sound_init) |
448 | module_exit(alsa_sound_exit) | 453 | module_exit(alsa_sound_exit) |
449 | |||
450 | /* sound.c */ | ||
451 | EXPORT_SYMBOL(snd_major); | ||
452 | EXPORT_SYMBOL(snd_ecards_limit); | ||
453 | #if defined(CONFIG_KMOD) | ||
454 | EXPORT_SYMBOL(snd_request_card); | ||
455 | #endif | ||
456 | EXPORT_SYMBOL(snd_register_device); | ||
457 | EXPORT_SYMBOL(snd_unregister_device); | ||
458 | EXPORT_SYMBOL(snd_lookup_minor_data); | ||
459 | #if defined(CONFIG_SND_OSSEMUL) | ||
460 | EXPORT_SYMBOL(snd_register_oss_device); | ||
461 | EXPORT_SYMBOL(snd_unregister_oss_device); | ||
462 | EXPORT_SYMBOL(snd_lookup_oss_minor_data); | ||
463 | #endif | ||
464 | /* memory.c */ | ||
465 | EXPORT_SYMBOL(copy_to_user_fromio); | ||
466 | EXPORT_SYMBOL(copy_from_user_toio); | ||
467 | /* init.c */ | ||
468 | EXPORT_SYMBOL(snd_cards); | ||
469 | #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) | ||
470 | EXPORT_SYMBOL(snd_mixer_oss_notify_callback); | ||
471 | #endif | ||
472 | EXPORT_SYMBOL(snd_card_new); | ||
473 | EXPORT_SYMBOL(snd_card_disconnect); | ||
474 | EXPORT_SYMBOL(snd_card_free); | ||
475 | EXPORT_SYMBOL(snd_card_free_in_thread); | ||
476 | EXPORT_SYMBOL(snd_card_register); | ||
477 | EXPORT_SYMBOL(snd_component_add); | ||
478 | EXPORT_SYMBOL(snd_card_file_add); | ||
479 | EXPORT_SYMBOL(snd_card_file_remove); | ||
480 | #ifdef CONFIG_PM | ||
481 | EXPORT_SYMBOL(snd_power_wait); | ||
482 | #endif | ||
483 | /* device.c */ | ||
484 | EXPORT_SYMBOL(snd_device_new); | ||
485 | EXPORT_SYMBOL(snd_device_register); | ||
486 | EXPORT_SYMBOL(snd_device_free); | ||
487 | /* isadma.c */ | ||
488 | #ifdef CONFIG_ISA_DMA_API | ||
489 | EXPORT_SYMBOL(snd_dma_program); | ||
490 | EXPORT_SYMBOL(snd_dma_disable); | ||
491 | EXPORT_SYMBOL(snd_dma_pointer); | ||
492 | #endif | ||
493 | /* info.c */ | ||
494 | #ifdef CONFIG_PROC_FS | ||
495 | EXPORT_SYMBOL(snd_seq_root); | ||
496 | EXPORT_SYMBOL(snd_iprintf); | ||
497 | EXPORT_SYMBOL(snd_info_get_line); | ||
498 | EXPORT_SYMBOL(snd_info_get_str); | ||
499 | EXPORT_SYMBOL(snd_info_create_module_entry); | ||
500 | EXPORT_SYMBOL(snd_info_create_card_entry); | ||
501 | EXPORT_SYMBOL(snd_info_free_entry); | ||
502 | EXPORT_SYMBOL(snd_info_register); | ||
503 | EXPORT_SYMBOL(snd_info_unregister); | ||
504 | EXPORT_SYMBOL(snd_card_proc_new); | ||
505 | #endif | ||
506 | /* info_oss.c */ | ||
507 | #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS) | ||
508 | EXPORT_SYMBOL(snd_oss_info_register); | ||
509 | #endif | ||
510 | /* control.c */ | ||
511 | EXPORT_SYMBOL(snd_ctl_new); | ||
512 | EXPORT_SYMBOL(snd_ctl_new1); | ||
513 | EXPORT_SYMBOL(snd_ctl_free_one); | ||
514 | EXPORT_SYMBOL(snd_ctl_add); | ||
515 | EXPORT_SYMBOL(snd_ctl_remove); | ||
516 | EXPORT_SYMBOL(snd_ctl_remove_id); | ||
517 | EXPORT_SYMBOL(snd_ctl_rename_id); | ||
518 | EXPORT_SYMBOL(snd_ctl_find_numid); | ||
519 | EXPORT_SYMBOL(snd_ctl_find_id); | ||
520 | EXPORT_SYMBOL(snd_ctl_notify); | ||
521 | EXPORT_SYMBOL(snd_ctl_register_ioctl); | ||
522 | EXPORT_SYMBOL(snd_ctl_unregister_ioctl); | ||
523 | #ifdef CONFIG_COMPAT | ||
524 | EXPORT_SYMBOL(snd_ctl_register_ioctl_compat); | ||
525 | EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat); | ||
526 | #endif | ||
527 | EXPORT_SYMBOL(snd_ctl_elem_read); | ||
528 | EXPORT_SYMBOL(snd_ctl_elem_write); | ||
529 | /* misc.c */ | ||
530 | EXPORT_SYMBOL(release_and_free_resource); | ||
531 | #ifdef CONFIG_SND_VERBOSE_PRINTK | ||
532 | EXPORT_SYMBOL(snd_verbose_printk); | ||
533 | #endif | ||
534 | #if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK) | ||
535 | EXPORT_SYMBOL(snd_verbose_printd); | ||
536 | #endif | ||
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index 9055c6de9587..74f0fe5a1ba0 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c | |||
@@ -58,6 +58,8 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type) | |||
58 | return private_data; | 58 | return private_data; |
59 | } | 59 | } |
60 | 60 | ||
61 | EXPORT_SYMBOL(snd_lookup_oss_minor_data); | ||
62 | |||
61 | static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) | 63 | static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) |
62 | { | 64 | { |
63 | int minor; | 65 | int minor; |
@@ -158,6 +160,8 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, | |||
158 | return -EBUSY; | 160 | return -EBUSY; |
159 | } | 161 | } |
160 | 162 | ||
163 | EXPORT_SYMBOL(snd_register_oss_device); | ||
164 | |||
161 | int snd_unregister_oss_device(int type, struct snd_card *card, int dev) | 165 | int snd_unregister_oss_device(int type, struct snd_card *card, int dev) |
162 | { | 166 | { |
163 | int minor = snd_oss_kernel_minor(type, card, dev); | 167 | int minor = snd_oss_kernel_minor(type, card, dev); |
@@ -197,13 +201,15 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) | |||
197 | return 0; | 201 | return 0; |
198 | } | 202 | } |
199 | 203 | ||
204 | EXPORT_SYMBOL(snd_unregister_oss_device); | ||
205 | |||
200 | /* | 206 | /* |
201 | * INFO PART | 207 | * INFO PART |
202 | */ | 208 | */ |
203 | 209 | ||
204 | #ifdef CONFIG_PROC_FS | 210 | #ifdef CONFIG_PROC_FS |
205 | 211 | ||
206 | static struct snd_info_entry *snd_minor_info_oss_entry = NULL; | 212 | static struct snd_info_entry *snd_minor_info_oss_entry; |
207 | 213 | ||
208 | static const char *snd_oss_device_type_name(int type) | 214 | static const char *snd_oss_device_type_name(int type) |
209 | { | 215 | { |
@@ -252,7 +258,6 @@ int __init snd_minor_info_oss_init(void) | |||
252 | 258 | ||
253 | entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root); | 259 | entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root); |
254 | if (entry) { | 260 | if (entry) { |
255 | entry->c.text.read_size = PAGE_SIZE; | ||
256 | entry->c.text.read = snd_minor_info_oss_read; | 261 | entry->c.text.read = snd_minor_info_oss_read; |
257 | if (snd_info_register(entry) < 0) { | 262 | if (snd_info_register(entry) < 0) { |
258 | snd_info_free_entry(entry); | 263 | snd_info_free_entry(entry); |
diff --git a/sound/core/timer.c b/sound/core/timer.c index cdeeb639b675..78199f58b93a 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -1061,7 +1061,6 @@ static int snd_timer_register_system(void) | |||
1061 | static void snd_timer_proc_read(struct snd_info_entry *entry, | 1061 | static void snd_timer_proc_read(struct snd_info_entry *entry, |
1062 | struct snd_info_buffer *buffer) | 1062 | struct snd_info_buffer *buffer) |
1063 | { | 1063 | { |
1064 | unsigned long flags; | ||
1065 | struct snd_timer *timer; | 1064 | struct snd_timer *timer; |
1066 | struct snd_timer_instance *ti; | 1065 | struct snd_timer_instance *ti; |
1067 | struct list_head *p, *q; | 1066 | struct list_head *p, *q; |
@@ -1095,7 +1094,6 @@ static void snd_timer_proc_read(struct snd_info_entry *entry, | |||
1095 | if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) | 1094 | if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) |
1096 | snd_iprintf(buffer, " SLAVE"); | 1095 | snd_iprintf(buffer, " SLAVE"); |
1097 | snd_iprintf(buffer, "\n"); | 1096 | snd_iprintf(buffer, "\n"); |
1098 | spin_lock_irqsave(&timer->lock, flags); | ||
1099 | list_for_each(q, &timer->open_list_head) { | 1097 | list_for_each(q, &timer->open_list_head) { |
1100 | ti = list_entry(q, struct snd_timer_instance, open_list); | 1098 | ti = list_entry(q, struct snd_timer_instance, open_list); |
1101 | snd_iprintf(buffer, " Client %s : %s\n", | 1099 | snd_iprintf(buffer, " Client %s : %s\n", |
@@ -1104,12 +1102,11 @@ static void snd_timer_proc_read(struct snd_info_entry *entry, | |||
1104 | SNDRV_TIMER_IFLG_RUNNING) | 1102 | SNDRV_TIMER_IFLG_RUNNING) |
1105 | ? "running" : "stopped"); | 1103 | ? "running" : "stopped"); |
1106 | } | 1104 | } |
1107 | spin_unlock_irqrestore(&timer->lock, flags); | ||
1108 | } | 1105 | } |
1109 | mutex_unlock(®ister_mutex); | 1106 | mutex_unlock(®ister_mutex); |
1110 | } | 1107 | } |
1111 | 1108 | ||
1112 | static struct snd_info_entry *snd_timer_proc_entry = NULL; | 1109 | static struct snd_info_entry *snd_timer_proc_entry; |
1113 | 1110 | ||
1114 | static void __init snd_timer_proc_init(void) | 1111 | static void __init snd_timer_proc_init(void) |
1115 | { | 1112 | { |
@@ -1117,7 +1114,6 @@ static void __init snd_timer_proc_init(void) | |||
1117 | 1114 | ||
1118 | entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL); | 1115 | entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL); |
1119 | if (entry != NULL) { | 1116 | if (entry != NULL) { |
1120 | entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128; | ||
1121 | entry->c.text.read = snd_timer_proc_read; | 1117 | entry->c.text.read = snd_timer_proc_read; |
1122 | if (snd_info_register(entry) < 0) { | 1118 | if (snd_info_register(entry) < 0) { |
1123 | snd_info_free_entry(entry); | 1119 | snd_info_free_entry(entry); |