diff options
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/control.c | 5 | ||||
-rw-r--r-- | sound/core/init.c | 9 | ||||
-rw-r--r-- | sound/core/oss/mixer_oss.c | 22 | ||||
-rw-r--r-- | sound/core/pcm.c | 42 | ||||
-rw-r--r-- | sound/core/pcm_lib.c | 25 | ||||
-rw-r--r-- | sound/core/pcm_misc.c | 16 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 21 | ||||
-rw-r--r-- | sound/core/rawmidi.c | 2 | ||||
-rw-r--r-- | sound/core/seq/oss/seq_oss_init.c | 9 |
9 files changed, 105 insertions, 46 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index 070aab49019..45a818002d9 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | /* max number of user-defined controls */ | 32 | /* max number of user-defined controls */ |
33 | #define MAX_USER_CONTROLS 32 | 33 | #define MAX_USER_CONTROLS 32 |
34 | #define MAX_CONTROL_COUNT 1028 | ||
34 | 35 | ||
35 | struct snd_kctl_ioctl { | 36 | struct snd_kctl_ioctl { |
36 | struct list_head list; /* list of all ioctls */ | 37 | struct list_head list; /* list of all ioctls */ |
@@ -195,6 +196,10 @@ static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, | |||
195 | 196 | ||
196 | if (snd_BUG_ON(!control || !control->count)) | 197 | if (snd_BUG_ON(!control || !control->count)) |
197 | return NULL; | 198 | return NULL; |
199 | |||
200 | if (control->count > MAX_CONTROL_COUNT) | ||
201 | return NULL; | ||
202 | |||
198 | kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL); | 203 | kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL); |
199 | if (kctl == NULL) { | 204 | if (kctl == NULL) { |
200 | snd_printk(KERN_ERR "Cannot allocate control instance\n"); | 205 | snd_printk(KERN_ERR "Cannot allocate control instance\n"); |
diff --git a/sound/core/init.c b/sound/core/init.c index ec4a50ce565..2de45fbd70f 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -607,11 +607,16 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr, | |||
607 | return -EEXIST; | 607 | return -EEXIST; |
608 | } | 608 | } |
609 | for (idx = 0; idx < snd_ecards_limit; idx++) { | 609 | for (idx = 0; idx < snd_ecards_limit; idx++) { |
610 | if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1)) | 610 | if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1)) { |
611 | goto __exist; | 611 | if (card == snd_cards[idx]) |
612 | goto __ok; | ||
613 | else | ||
614 | goto __exist; | ||
615 | } | ||
612 | } | 616 | } |
613 | strcpy(card->id, buf1); | 617 | strcpy(card->id, buf1); |
614 | snd_info_card_id_change(card); | 618 | snd_info_card_id_change(card); |
619 | __ok: | ||
615 | mutex_unlock(&snd_card_mutex); | 620 | mutex_unlock(&snd_card_mutex); |
616 | 621 | ||
617 | return count; | 622 | return count; |
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 8442a088677..822dd56993c 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c | |||
@@ -77,7 +77,7 @@ static int snd_mixer_oss_release(struct inode *inode, struct file *file) | |||
77 | struct snd_mixer_oss_file *fmixer; | 77 | struct snd_mixer_oss_file *fmixer; |
78 | 78 | ||
79 | if (file->private_data) { | 79 | if (file->private_data) { |
80 | fmixer = (struct snd_mixer_oss_file *) file->private_data; | 80 | fmixer = file->private_data; |
81 | module_put(fmixer->card->module); | 81 | module_put(fmixer->card->module); |
82 | snd_card_file_remove(fmixer->card, file); | 82 | snd_card_file_remove(fmixer->card, file); |
83 | kfree(fmixer); | 83 | kfree(fmixer); |
@@ -368,7 +368,7 @@ static int snd_mixer_oss_ioctl1(struct snd_mixer_oss_file *fmixer, unsigned int | |||
368 | 368 | ||
369 | static long snd_mixer_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 369 | static long snd_mixer_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
370 | { | 370 | { |
371 | return snd_mixer_oss_ioctl1((struct snd_mixer_oss_file *) file->private_data, cmd, arg); | 371 | return snd_mixer_oss_ioctl1(file->private_data, cmd, arg); |
372 | } | 372 | } |
373 | 373 | ||
374 | int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned long arg) | 374 | int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned long arg) |
@@ -582,7 +582,7 @@ static int snd_mixer_oss_get_volume1(struct snd_mixer_oss_file *fmixer, | |||
582 | struct snd_mixer_oss_slot *pslot, | 582 | struct snd_mixer_oss_slot *pslot, |
583 | int *left, int *right) | 583 | int *left, int *right) |
584 | { | 584 | { |
585 | struct slot *slot = (struct slot *)pslot->private_data; | 585 | struct slot *slot = pslot->private_data; |
586 | 586 | ||
587 | *left = *right = 100; | 587 | *left = *right = 100; |
588 | if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) { | 588 | if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) { |
@@ -693,7 +693,7 @@ static int snd_mixer_oss_put_volume1(struct snd_mixer_oss_file *fmixer, | |||
693 | struct snd_mixer_oss_slot *pslot, | 693 | struct snd_mixer_oss_slot *pslot, |
694 | int left, int right) | 694 | int left, int right) |
695 | { | 695 | { |
696 | struct slot *slot = (struct slot *)pslot->private_data; | 696 | struct slot *slot = pslot->private_data; |
697 | 697 | ||
698 | if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) { | 698 | if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) { |
699 | snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right); | 699 | snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right); |
@@ -742,7 +742,7 @@ static int snd_mixer_oss_get_recsrc1_sw(struct snd_mixer_oss_file *fmixer, | |||
742 | struct snd_mixer_oss_slot *pslot, | 742 | struct snd_mixer_oss_slot *pslot, |
743 | int *active) | 743 | int *active) |
744 | { | 744 | { |
745 | struct slot *slot = (struct slot *)pslot->private_data; | 745 | struct slot *slot = pslot->private_data; |
746 | int left, right; | 746 | int left, right; |
747 | 747 | ||
748 | left = right = 1; | 748 | left = right = 1; |
@@ -755,7 +755,7 @@ static int snd_mixer_oss_get_recsrc1_route(struct snd_mixer_oss_file *fmixer, | |||
755 | struct snd_mixer_oss_slot *pslot, | 755 | struct snd_mixer_oss_slot *pslot, |
756 | int *active) | 756 | int *active) |
757 | { | 757 | { |
758 | struct slot *slot = (struct slot *)pslot->private_data; | 758 | struct slot *slot = pslot->private_data; |
759 | int left, right; | 759 | int left, right; |
760 | 760 | ||
761 | left = right = 1; | 761 | left = right = 1; |
@@ -768,7 +768,7 @@ static int snd_mixer_oss_put_recsrc1_sw(struct snd_mixer_oss_file *fmixer, | |||
768 | struct snd_mixer_oss_slot *pslot, | 768 | struct snd_mixer_oss_slot *pslot, |
769 | int active) | 769 | int active) |
770 | { | 770 | { |
771 | struct slot *slot = (struct slot *)pslot->private_data; | 771 | struct slot *slot = pslot->private_data; |
772 | 772 | ||
773 | snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], active, active, 0); | 773 | snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], active, active, 0); |
774 | return 0; | 774 | return 0; |
@@ -778,7 +778,7 @@ static int snd_mixer_oss_put_recsrc1_route(struct snd_mixer_oss_file *fmixer, | |||
778 | struct snd_mixer_oss_slot *pslot, | 778 | struct snd_mixer_oss_slot *pslot, |
779 | int active) | 779 | int active) |
780 | { | 780 | { |
781 | struct slot *slot = (struct slot *)pslot->private_data; | 781 | struct slot *slot = pslot->private_data; |
782 | 782 | ||
783 | snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], active, active, 1); | 783 | snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], active, active, 1); |
784 | return 0; | 784 | return 0; |
@@ -815,7 +815,7 @@ static int snd_mixer_oss_get_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned | |||
815 | if (!(mixer->mask_recsrc & (1 << idx))) | 815 | if (!(mixer->mask_recsrc & (1 << idx))) |
816 | continue; | 816 | continue; |
817 | pslot = &mixer->slots[idx]; | 817 | pslot = &mixer->slots[idx]; |
818 | slot = (struct slot *)pslot->private_data; | 818 | slot = pslot->private_data; |
819 | if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE) | 819 | if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE) |
820 | continue; | 820 | continue; |
821 | if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE)) | 821 | if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE)) |
@@ -864,7 +864,7 @@ static int snd_mixer_oss_put_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned | |||
864 | if (!(mixer->mask_recsrc & (1 << idx))) | 864 | if (!(mixer->mask_recsrc & (1 << idx))) |
865 | continue; | 865 | continue; |
866 | pslot = &mixer->slots[idx]; | 866 | pslot = &mixer->slots[idx]; |
867 | slot = (struct slot *)pslot->private_data; | 867 | slot = pslot->private_data; |
868 | if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE) | 868 | if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE) |
869 | continue; | 869 | continue; |
870 | if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE)) | 870 | if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE)) |
@@ -929,7 +929,7 @@ static int snd_mixer_oss_build_test(struct snd_mixer_oss *mixer, struct slot *sl | |||
929 | 929 | ||
930 | static void snd_mixer_oss_slot_free(struct snd_mixer_oss_slot *chn) | 930 | static void snd_mixer_oss_slot_free(struct snd_mixer_oss_slot *chn) |
931 | { | 931 | { |
932 | struct slot *p = (struct slot *)chn->private_data; | 932 | struct slot *p = chn->private_data; |
933 | if (p) { | 933 | if (p) { |
934 | if (p->allocated && p->assigned) { | 934 | if (p->allocated && p->assigned) { |
935 | kfree(p->assigned->name); | 935 | kfree(p->assigned->name); |
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index cbe815dfbdc..6b4b1287b31 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -203,10 +203,16 @@ static char *snd_pcm_format_names[] = { | |||
203 | FORMAT(S18_3BE), | 203 | FORMAT(S18_3BE), |
204 | FORMAT(U18_3LE), | 204 | FORMAT(U18_3LE), |
205 | FORMAT(U18_3BE), | 205 | FORMAT(U18_3BE), |
206 | FORMAT(G723_24), | ||
207 | FORMAT(G723_24_1B), | ||
208 | FORMAT(G723_40), | ||
209 | FORMAT(G723_40_1B), | ||
206 | }; | 210 | }; |
207 | 211 | ||
208 | const char *snd_pcm_format_name(snd_pcm_format_t format) | 212 | const char *snd_pcm_format_name(snd_pcm_format_t format) |
209 | { | 213 | { |
214 | if (format >= ARRAY_SIZE(snd_pcm_format_names)) | ||
215 | return "Unknown"; | ||
210 | return snd_pcm_format_names[format]; | 216 | return snd_pcm_format_names[format]; |
211 | } | 217 | } |
212 | EXPORT_SYMBOL_GPL(snd_pcm_format_name); | 218 | EXPORT_SYMBOL_GPL(snd_pcm_format_name); |
@@ -358,22 +364,24 @@ static void snd_pcm_stream_proc_info_read(struct snd_info_entry *entry, | |||
358 | static void snd_pcm_substream_proc_info_read(struct snd_info_entry *entry, | 364 | static void snd_pcm_substream_proc_info_read(struct snd_info_entry *entry, |
359 | struct snd_info_buffer *buffer) | 365 | struct snd_info_buffer *buffer) |
360 | { | 366 | { |
361 | snd_pcm_proc_info_read((struct snd_pcm_substream *)entry->private_data, | 367 | snd_pcm_proc_info_read(entry->private_data, buffer); |
362 | buffer); | ||
363 | } | 368 | } |
364 | 369 | ||
365 | static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry, | 370 | static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry, |
366 | struct snd_info_buffer *buffer) | 371 | struct snd_info_buffer *buffer) |
367 | { | 372 | { |
368 | struct snd_pcm_substream *substream = entry->private_data; | 373 | struct snd_pcm_substream *substream = entry->private_data; |
369 | struct snd_pcm_runtime *runtime = substream->runtime; | 374 | struct snd_pcm_runtime *runtime; |
375 | |||
376 | mutex_lock(&substream->pcm->open_mutex); | ||
377 | runtime = substream->runtime; | ||
370 | if (!runtime) { | 378 | if (!runtime) { |
371 | snd_iprintf(buffer, "closed\n"); | 379 | snd_iprintf(buffer, "closed\n"); |
372 | return; | 380 | goto unlock; |
373 | } | 381 | } |
374 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { | 382 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { |
375 | snd_iprintf(buffer, "no setup\n"); | 383 | snd_iprintf(buffer, "no setup\n"); |
376 | return; | 384 | goto unlock; |
377 | } | 385 | } |
378 | snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access)); | 386 | snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access)); |
379 | snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format)); | 387 | snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format)); |
@@ -392,20 +400,25 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry, | |||
392 | snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames); | 400 | snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames); |
393 | } | 401 | } |
394 | #endif | 402 | #endif |
403 | unlock: | ||
404 | mutex_unlock(&substream->pcm->open_mutex); | ||
395 | } | 405 | } |
396 | 406 | ||
397 | static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, | 407 | static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, |
398 | struct snd_info_buffer *buffer) | 408 | struct snd_info_buffer *buffer) |
399 | { | 409 | { |
400 | struct snd_pcm_substream *substream = entry->private_data; | 410 | struct snd_pcm_substream *substream = entry->private_data; |
401 | struct snd_pcm_runtime *runtime = substream->runtime; | 411 | struct snd_pcm_runtime *runtime; |
412 | |||
413 | mutex_lock(&substream->pcm->open_mutex); | ||
414 | runtime = substream->runtime; | ||
402 | if (!runtime) { | 415 | if (!runtime) { |
403 | snd_iprintf(buffer, "closed\n"); | 416 | snd_iprintf(buffer, "closed\n"); |
404 | return; | 417 | goto unlock; |
405 | } | 418 | } |
406 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { | 419 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { |
407 | snd_iprintf(buffer, "no setup\n"); | 420 | snd_iprintf(buffer, "no setup\n"); |
408 | return; | 421 | goto unlock; |
409 | } | 422 | } |
410 | snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode)); | 423 | snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode)); |
411 | snd_iprintf(buffer, "period_step: %u\n", runtime->period_step); | 424 | snd_iprintf(buffer, "period_step: %u\n", runtime->period_step); |
@@ -415,24 +428,29 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, | |||
415 | snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); | 428 | snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); |
416 | snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size); | 429 | snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size); |
417 | snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary); | 430 | snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary); |
431 | unlock: | ||
432 | mutex_unlock(&substream->pcm->open_mutex); | ||
418 | } | 433 | } |
419 | 434 | ||
420 | static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, | 435 | static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, |
421 | struct snd_info_buffer *buffer) | 436 | struct snd_info_buffer *buffer) |
422 | { | 437 | { |
423 | struct snd_pcm_substream *substream = entry->private_data; | 438 | struct snd_pcm_substream *substream = entry->private_data; |
424 | struct snd_pcm_runtime *runtime = substream->runtime; | 439 | struct snd_pcm_runtime *runtime; |
425 | struct snd_pcm_status status; | 440 | struct snd_pcm_status status; |
426 | int err; | 441 | int err; |
442 | |||
443 | mutex_lock(&substream->pcm->open_mutex); | ||
444 | runtime = substream->runtime; | ||
427 | if (!runtime) { | 445 | if (!runtime) { |
428 | snd_iprintf(buffer, "closed\n"); | 446 | snd_iprintf(buffer, "closed\n"); |
429 | return; | 447 | goto unlock; |
430 | } | 448 | } |
431 | memset(&status, 0, sizeof(status)); | 449 | memset(&status, 0, sizeof(status)); |
432 | err = snd_pcm_status(substream, &status); | 450 | err = snd_pcm_status(substream, &status); |
433 | if (err < 0) { | 451 | if (err < 0) { |
434 | snd_iprintf(buffer, "error %d\n", err); | 452 | snd_iprintf(buffer, "error %d\n", err); |
435 | return; | 453 | goto unlock; |
436 | } | 454 | } |
437 | snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state)); | 455 | snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state)); |
438 | snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid)); | 456 | snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid)); |
@@ -446,6 +464,8 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, | |||
446 | snd_iprintf(buffer, "-----\n"); | 464 | snd_iprintf(buffer, "-----\n"); |
447 | snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr); | 465 | snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr); |
448 | snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr); | 466 | snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr); |
467 | unlock: | ||
468 | mutex_unlock(&substream->pcm->open_mutex); | ||
449 | } | 469 | } |
450 | 470 | ||
451 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG | 471 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index d6ecca27bb6..a1707cca9c6 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -67,6 +67,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram | |||
67 | } else { | 67 | } else { |
68 | if (new_hw_ptr == ULONG_MAX) { /* initialization */ | 68 | if (new_hw_ptr == ULONG_MAX) { /* initialization */ |
69 | snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime); | 69 | snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime); |
70 | if (avail > runtime->buffer_size) | ||
71 | avail = runtime->buffer_size; | ||
70 | runtime->silence_filled = avail > 0 ? avail : 0; | 72 | runtime->silence_filled = avail > 0 ? avail : 0; |
71 | runtime->silence_start = (runtime->status->hw_ptr + | 73 | runtime->silence_start = (runtime->status->hw_ptr + |
72 | runtime->silence_filled) % | 74 | runtime->silence_filled) % |
@@ -287,8 +289,11 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream, | |||
287 | return -EPIPE; | 289 | return -EPIPE; |
288 | } | 290 | } |
289 | } | 291 | } |
290 | if (avail >= runtime->control->avail_min) | 292 | if (runtime->twake) { |
291 | wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep); | 293 | if (avail >= runtime->twake) |
294 | wake_up(&runtime->tsleep); | ||
295 | } else if (avail >= runtime->control->avail_min) | ||
296 | wake_up(&runtime->sleep); | ||
292 | return 0; | 297 | return 0; |
293 | } | 298 | } |
294 | 299 | ||
@@ -1711,7 +1716,7 @@ EXPORT_SYMBOL(snd_pcm_period_elapsed); | |||
1711 | * The available space is stored on availp. When err = 0 and avail = 0 | 1716 | * The available space is stored on availp. When err = 0 and avail = 0 |
1712 | * on the capture stream, it indicates the stream is in DRAINING state. | 1717 | * on the capture stream, it indicates the stream is in DRAINING state. |
1713 | */ | 1718 | */ |
1714 | static int wait_for_avail_min(struct snd_pcm_substream *substream, | 1719 | static int wait_for_avail(struct snd_pcm_substream *substream, |
1715 | snd_pcm_uframes_t *availp) | 1720 | snd_pcm_uframes_t *availp) |
1716 | { | 1721 | { |
1717 | struct snd_pcm_runtime *runtime = substream->runtime; | 1722 | struct snd_pcm_runtime *runtime = substream->runtime; |
@@ -1761,7 +1766,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream, | |||
1761 | avail = snd_pcm_playback_avail(runtime); | 1766 | avail = snd_pcm_playback_avail(runtime); |
1762 | else | 1767 | else |
1763 | avail = snd_pcm_capture_avail(runtime); | 1768 | avail = snd_pcm_capture_avail(runtime); |
1764 | if (avail >= runtime->control->avail_min) | 1769 | if (avail >= runtime->twake) |
1765 | break; | 1770 | break; |
1766 | } | 1771 | } |
1767 | _endloop: | 1772 | _endloop: |
@@ -1824,7 +1829,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, | |||
1824 | goto _end_unlock; | 1829 | goto _end_unlock; |
1825 | } | 1830 | } |
1826 | 1831 | ||
1827 | runtime->twake = 1; | 1832 | runtime->twake = runtime->control->avail_min ? : 1; |
1828 | while (size > 0) { | 1833 | while (size > 0) { |
1829 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; | 1834 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; |
1830 | snd_pcm_uframes_t avail; | 1835 | snd_pcm_uframes_t avail; |
@@ -1837,7 +1842,9 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, | |||
1837 | err = -EAGAIN; | 1842 | err = -EAGAIN; |
1838 | goto _end_unlock; | 1843 | goto _end_unlock; |
1839 | } | 1844 | } |
1840 | err = wait_for_avail_min(substream, &avail); | 1845 | runtime->twake = min_t(snd_pcm_uframes_t, size, |
1846 | runtime->control->avail_min ? : 1); | ||
1847 | err = wait_for_avail(substream, &avail); | ||
1841 | if (err < 0) | 1848 | if (err < 0) |
1842 | goto _end_unlock; | 1849 | goto _end_unlock; |
1843 | } | 1850 | } |
@@ -2046,7 +2053,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, | |||
2046 | goto _end_unlock; | 2053 | goto _end_unlock; |
2047 | } | 2054 | } |
2048 | 2055 | ||
2049 | runtime->twake = 1; | 2056 | runtime->twake = runtime->control->avail_min ? : 1; |
2050 | while (size > 0) { | 2057 | while (size > 0) { |
2051 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; | 2058 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; |
2052 | snd_pcm_uframes_t avail; | 2059 | snd_pcm_uframes_t avail; |
@@ -2064,7 +2071,9 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, | |||
2064 | err = -EAGAIN; | 2071 | err = -EAGAIN; |
2065 | goto _end_unlock; | 2072 | goto _end_unlock; |
2066 | } | 2073 | } |
2067 | err = wait_for_avail_min(substream, &avail); | 2074 | runtime->twake = min_t(snd_pcm_uframes_t, size, |
2075 | runtime->control->avail_min ? : 1); | ||
2076 | err = wait_for_avail(substream, &avail); | ||
2068 | if (err < 0) | 2077 | if (err < 0) |
2069 | goto _end_unlock; | 2078 | goto _end_unlock; |
2070 | if (!avail) | 2079 | if (!avail) |
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index ea2bf82c937..434af3c56d5 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c | |||
@@ -128,6 +128,14 @@ static struct pcm_format_data pcm_formats[SNDRV_PCM_FORMAT_LAST+1] = { | |||
128 | .width = 4, .phys = 4, .le = -1, .signd = -1, | 128 | .width = 4, .phys = 4, .le = -1, .signd = -1, |
129 | .silence = {}, | 129 | .silence = {}, |
130 | }, | 130 | }, |
131 | [SNDRV_PCM_FORMAT_G723_24] = { | ||
132 | .width = 3, .phys = 3, .le = -1, .signd = -1, | ||
133 | .silence = {}, | ||
134 | }, | ||
135 | [SNDRV_PCM_FORMAT_G723_40] = { | ||
136 | .width = 5, .phys = 5, .le = -1, .signd = -1, | ||
137 | .silence = {}, | ||
138 | }, | ||
131 | /* FIXME: the following three formats are not defined properly yet */ | 139 | /* FIXME: the following three formats are not defined properly yet */ |
132 | [SNDRV_PCM_FORMAT_MPEG] = { | 140 | [SNDRV_PCM_FORMAT_MPEG] = { |
133 | .le = -1, .signd = -1, | 141 | .le = -1, .signd = -1, |
@@ -186,6 +194,14 @@ static struct pcm_format_data pcm_formats[SNDRV_PCM_FORMAT_LAST+1] = { | |||
186 | .width = 18, .phys = 24, .le = 0, .signd = 0, | 194 | .width = 18, .phys = 24, .le = 0, .signd = 0, |
187 | .silence = { 0x02, 0x00, 0x00 }, | 195 | .silence = { 0x02, 0x00, 0x00 }, |
188 | }, | 196 | }, |
197 | [SNDRV_PCM_FORMAT_G723_24_1B] = { | ||
198 | .width = 3, .phys = 8, .le = -1, .signd = -1, | ||
199 | .silence = {}, | ||
200 | }, | ||
201 | [SNDRV_PCM_FORMAT_G723_40_1B] = { | ||
202 | .width = 5, .phys = 8, .le = -1, .signd = -1, | ||
203 | .silence = {}, | ||
204 | }, | ||
189 | }; | 205 | }; |
190 | 206 | ||
191 | 207 | ||
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 2d2e1b65ee9..8bc7cb3db33 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -142,7 +142,7 @@ int snd_pcm_info_user(struct snd_pcm_substream *substream, | |||
142 | 142 | ||
143 | #ifdef RULES_DEBUG | 143 | #ifdef RULES_DEBUG |
144 | #define HW_PARAM(v) [SNDRV_PCM_HW_PARAM_##v] = #v | 144 | #define HW_PARAM(v) [SNDRV_PCM_HW_PARAM_##v] = #v |
145 | char *snd_pcm_hw_param_names[] = { | 145 | static const char * const snd_pcm_hw_param_names[] = { |
146 | HW_PARAM(ACCESS), | 146 | HW_PARAM(ACCESS), |
147 | HW_PARAM(FORMAT), | 147 | HW_PARAM(FORMAT), |
148 | HW_PARAM(SUBFORMAT), | 148 | HW_PARAM(SUBFORMAT), |
@@ -451,13 +451,11 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, | |||
451 | snd_pcm_timer_resolution_change(substream); | 451 | snd_pcm_timer_resolution_change(substream); |
452 | runtime->status->state = SNDRV_PCM_STATE_SETUP; | 452 | runtime->status->state = SNDRV_PCM_STATE_SETUP; |
453 | 453 | ||
454 | if (substream->latency_pm_qos_req) { | 454 | if (pm_qos_request_active(&substream->latency_pm_qos_req)) |
455 | pm_qos_remove_request(substream->latency_pm_qos_req); | 455 | pm_qos_remove_request(&substream->latency_pm_qos_req); |
456 | substream->latency_pm_qos_req = NULL; | ||
457 | } | ||
458 | if ((usecs = period_to_usecs(runtime)) >= 0) | 456 | if ((usecs = period_to_usecs(runtime)) >= 0) |
459 | substream->latency_pm_qos_req = pm_qos_add_request( | 457 | pm_qos_add_request(&substream->latency_pm_qos_req, |
460 | PM_QOS_CPU_DMA_LATENCY, usecs); | 458 | PM_QOS_CPU_DMA_LATENCY, usecs); |
461 | return 0; | 459 | return 0; |
462 | _error: | 460 | _error: |
463 | /* hardware might be unuseable from this time, | 461 | /* hardware might be unuseable from this time, |
@@ -512,8 +510,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) | |||
512 | if (substream->ops->hw_free) | 510 | if (substream->ops->hw_free) |
513 | result = substream->ops->hw_free(substream); | 511 | result = substream->ops->hw_free(substream); |
514 | runtime->status->state = SNDRV_PCM_STATE_OPEN; | 512 | runtime->status->state = SNDRV_PCM_STATE_OPEN; |
515 | pm_qos_remove_request(substream->latency_pm_qos_req); | 513 | pm_qos_remove_request(&substream->latency_pm_qos_req); |
516 | substream->latency_pm_qos_req = NULL; | ||
517 | return result; | 514 | return result; |
518 | } | 515 | } |
519 | 516 | ||
@@ -983,6 +980,10 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push) | |||
983 | { | 980 | { |
984 | if (substream->runtime->trigger_master != substream) | 981 | if (substream->runtime->trigger_master != substream) |
985 | return 0; | 982 | return 0; |
983 | /* some drivers might use hw_ptr to recover from the pause - | ||
984 | update the hw_ptr now */ | ||
985 | if (push) | ||
986 | snd_pcm_update_hw_ptr(substream); | ||
986 | /* The jiffies check in snd_pcm_update_hw_ptr*() is done by | 987 | /* The jiffies check in snd_pcm_update_hw_ptr*() is done by |
987 | * a delta betwen the current jiffies, this gives a large enough | 988 | * a delta betwen the current jiffies, this gives a large enough |
988 | * delta, effectively to skip the check once. | 989 | * delta, effectively to skip the check once. |
@@ -1993,6 +1994,8 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream) | |||
1993 | substream->ops->close(substream); | 1994 | substream->ops->close(substream); |
1994 | substream->hw_opened = 0; | 1995 | substream->hw_opened = 0; |
1995 | } | 1996 | } |
1997 | if (pm_qos_request_active(&substream->latency_pm_qos_req)) | ||
1998 | pm_qos_remove_request(&substream->latency_pm_qos_req); | ||
1996 | if (substream->pcm_release) { | 1999 | if (substream->pcm_release) { |
1997 | substream->pcm_release(substream); | 2000 | substream->pcm_release(substream); |
1998 | substream->pcm_release = NULL; | 2001 | substream->pcm_release = NULL; |
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index eb68326c37d..a7868ad4d53 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c | |||
@@ -829,6 +829,8 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, | |||
829 | 829 | ||
830 | if (get_user(device, (int __user *)argp)) | 830 | if (get_user(device, (int __user *)argp)) |
831 | return -EFAULT; | 831 | return -EFAULT; |
832 | if (device >= SNDRV_RAWMIDI_DEVICES) /* next device is -1 */ | ||
833 | device = SNDRV_RAWMIDI_DEVICES - 1; | ||
832 | mutex_lock(®ister_mutex); | 834 | mutex_lock(®ister_mutex); |
833 | device = device < 0 ? 0 : device + 1; | 835 | device = device < 0 ? 0 : device + 1; |
834 | while (device < SNDRV_RAWMIDI_DEVICES) { | 836 | while (device < SNDRV_RAWMIDI_DEVICES) { |
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c index 685712276ac..69cd7b3c362 100644 --- a/sound/core/seq/oss/seq_oss_init.c +++ b/sound/core/seq/oss/seq_oss_init.c | |||
@@ -281,13 +281,10 @@ snd_seq_oss_open(struct file *file, int level) | |||
281 | return 0; | 281 | return 0; |
282 | 282 | ||
283 | _error: | 283 | _error: |
284 | snd_seq_oss_writeq_delete(dp->writeq); | ||
285 | snd_seq_oss_readq_delete(dp->readq); | ||
286 | snd_seq_oss_synth_cleanup(dp); | 284 | snd_seq_oss_synth_cleanup(dp); |
287 | snd_seq_oss_midi_cleanup(dp); | 285 | snd_seq_oss_midi_cleanup(dp); |
288 | delete_port(dp); | ||
289 | delete_seq_queue(dp->queue); | 286 | delete_seq_queue(dp->queue); |
290 | kfree(dp); | 287 | delete_port(dp); |
291 | 288 | ||
292 | return rc; | 289 | return rc; |
293 | } | 290 | } |
@@ -350,8 +347,10 @@ create_port(struct seq_oss_devinfo *dp) | |||
350 | static int | 347 | static int |
351 | delete_port(struct seq_oss_devinfo *dp) | 348 | delete_port(struct seq_oss_devinfo *dp) |
352 | { | 349 | { |
353 | if (dp->port < 0) | 350 | if (dp->port < 0) { |
351 | kfree(dp); | ||
354 | return 0; | 352 | return 0; |
353 | } | ||
355 | 354 | ||
356 | debug_printk(("delete_port %i\n", dp->port)); | 355 | debug_printk(("delete_port %i\n", dp->port)); |
357 | return snd_seq_event_port_detach(dp->cseq, dp->port); | 356 | return snd_seq_event_port_detach(dp->cseq, dp->port); |