| @@ -685,33 +685,40 @@ static int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, · 684 unmodified lines |
| 685 | return 0; | 685 | return 0; |
| 686 | } | 686 | } |
| 687 | | 687 | |
| | 688 | #if IS_ENABLED(CONFIG_SND_PCM_OSS) |
| | 689 | #define is_oss_stream(substream) ((substream)->oss.oss) |
| | 690 | #else |
| | 691 | #define is_oss_stream(substream) false |
| | 692 | #endif |
| | 693 | |
| 688 | static int snd_pcm_hw_params(struct snd_pcm_substream *substream, | 694 | static int snd_pcm_hw_params(struct snd_pcm_substream *substream, |
| 689 | struct snd_pcm_hw_params *params) | 695 | struct snd_pcm_hw_params *params) |
| 690 | { | 696 | { |
| 691 | struct snd_pcm_runtime *runtime; | 697 | struct snd_pcm_runtime *runtime; |
| 692 | int err, usecs; | 698 | int err = 0, usecs; |
| 693 | unsigned int bits; | 699 | unsigned int bits; |
| 694 | snd_pcm_uframes_t frames; | 700 | snd_pcm_uframes_t frames; |
| 695 | | 701 | |
| 696 | if (PCM_RUNTIME_CHECK(substream)) | 702 | if (PCM_RUNTIME_CHECK(substream)) |
| 697 | return -ENXIO; | 703 | return -ENXIO; |
| 698 | runtime = substream->runtime; | 704 | runtime = substream->runtime; |
| | 705 | mutex_lock(&runtime->buffer_mutex); |
| 699 | snd_pcm_stream_lock_irq(substream); | 706 | snd_pcm_stream_lock_irq(substream); |
| 700 | switch (runtime->status->state) { | 707 | switch (runtime->status->state) { |
| 701 | case SNDRV_PCM_STATE_OPEN: | 708 | case SNDRV_PCM_STATE_OPEN: |
| 702 | case SNDRV_PCM_STATE_SETUP: | 709 | case SNDRV_PCM_STATE_SETUP: |
| 703 | case SNDRV_PCM_STATE_PREPARED: | 710 | case SNDRV_PCM_STATE_PREPARED: |
| | 711 | if (!is_oss_stream(substream) && |
| | 712 | atomic_read(&substream->mmap_count)) |
| | 713 | err = -EBADFD; |
| 704 | break; | 714 | break; |
| 705 | default: | 715 | default: |
| 706 | snd_pcm_stream_unlock_irq(substream); | 716 | err = -EBADFD; |
| 707 | return -EBADFD; | 717 | break; |
| 708 | } | 718 | } |
| 709 | snd_pcm_stream_unlock_irq(substream); | 719 | snd_pcm_stream_unlock_irq(substream); |
| 710 | #if IS_ENABLED(CONFIG_SND_PCM_OSS) | 720 | if (err) |
| 711 | if (!substream->oss.oss) | 721 | goto unlock; |
| 712 | #endif | | |
| 713 | if (atomic_read(&substream->mmap_count)) | | |
| 714 | return -EBADFD; | | |
| 715 | | 722 | |
| 716 | snd_pcm_sync_stop(substream, true); | 723 | snd_pcm_sync_stop(substream, true); |
| 717 | | 724 | |
| @@ -799,16 +806,21 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, · 81 unmodified lines |
| 799 | if (usecs >= 0) | 806 | if (usecs >= 0) |
| 800 | cpu_latency_qos_add_request(&substream->latency_pm_qos_req, | 807 | cpu_latency_qos_add_request(&substream->latency_pm_qos_req, |
| 801 | usecs); | 808 | usecs); |
| 802 | return 0; | 809 | err = 0; |
| 803 | _error: | 810 | _error: |
| 804 | /* hardware might be unusable from this time, | 811 | if (err) { |
| 805 | so we force application to retry to set | 812 | /* hardware might be unusable from this time, |
| 806 | the correct hardware parameter settings */ | 813 | * so we force application to retry to set |
| 807 | snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); | 814 | * the correct hardware parameter settings |
| 808 | if (substream->ops->hw_free != NULL) | 815 | */ |
| 809 | substream->ops->hw_free(substream); | 816 | snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); |
| 810 | if (substream->managed_buffer_alloc) | 817 | if (substream->ops->hw_free != NULL) |
| 811 | snd_pcm_lib_free_pages(substream); | 818 | substream->ops->hw_free(substream); |
| | 819 | if (substream->managed_buffer_alloc) |
| | 820 | snd_pcm_lib_free_pages(substream); |
| | 821 | } |
| | 822 | unlock: |
| | 823 | mutex_unlock(&runtime->buffer_mutex); |
| 812 | return err; | 824 | return err; |
| 813 | } | 825 | } |
| 814 | | 826 | |
| @@ -848,26 +860,31 @@ static int do_hw_free(struct snd_pcm_substream *substream) · 33 unmodified lines |
| 848 | static int snd_pcm_hw_free(struct snd_pcm_substream *substream) | 860 | static int snd_pcm_hw_free(struct snd_pcm_substream *substream) |
| 849 | { | 861 | { |
| 850 | struct snd_pcm_runtime *runtime; | 862 | struct snd_pcm_runtime *runtime; |
| 851 | int result; | 863 | int result = 0; |
| 852 | | 864 | |
| 853 | if (PCM_RUNTIME_CHECK(substream)) | 865 | if (PCM_RUNTIME_CHECK(substream)) |
| 854 | return -ENXIO; | 866 | return -ENXIO; |
| 855 | runtime = substream->runtime; | 867 | runtime = substream->runtime; |
| | 868 | mutex_lock(&runtime->buffer_mutex); |
| 856 | snd_pcm_stream_lock_irq(substream); | 869 | snd_pcm_stream_lock_irq(substream); |
| 857 | switch (runtime->status->state) { | 870 | switch (runtime->status->state) { |
| 858 | case SNDRV_PCM_STATE_SETUP: | 871 | case SNDRV_PCM_STATE_SETUP: |
| 859 | case SNDRV_PCM_STATE_PREPARED: | 872 | case SNDRV_PCM_STATE_PREPARED: |
| | 873 | if (atomic_read(&substream->mmap_count)) |
| | 874 | result = -EBADFD; |
| 860 | break; | 875 | break; |
| 861 | default: | 876 | default: |
| 862 | snd_pcm_stream_unlock_irq(substream); | 877 | result = -EBADFD; |
| 863 | return -EBADFD; | 878 | break; |
| 864 | } | 879 | } |
| 865 | snd_pcm_stream_unlock_irq(substream); | 880 | snd_pcm_stream_unlock_irq(substream); |
| 866 | if (atomic_read(&substream->mmap_count)) | 881 | if (result) |
| 867 | return -EBADFD; | 882 | goto unlock; |
| 868 | result = do_hw_free(substream); | 883 | result = do_hw_free(substream); |
| 869 | snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); | 884 | snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); |
| 870 | cpu_latency_qos_remove_request(&substream->latency_pm_qos_req); | 885 | cpu_latency_qos_remove_request(&substream->latency_pm_qos_req); |
| | 886 | unlock: |
| | 887 | mutex_unlock(&runtime->buffer_mutex); |
| 871 | return result; | 888 | return result; |
| 872 | } | 889 | } |
| 873 | | 890 | |