diff options
Diffstat (limited to 'sound/core/pcm_native.c')
-rw-r--r-- | sound/core/pcm_native.c | 153 |
1 files changed, 80 insertions, 73 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index c49b9d9e303..e61e12506de 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -95,7 +95,6 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info) | |||
95 | struct snd_pcm *pcm = substream->pcm; | 95 | struct snd_pcm *pcm = substream->pcm; |
96 | struct snd_pcm_str *pstr = substream->pstr; | 96 | struct snd_pcm_str *pstr = substream->pstr; |
97 | 97 | ||
98 | snd_assert(substream != NULL, return -ENXIO); | ||
99 | memset(info, 0, sizeof(*info)); | 98 | memset(info, 0, sizeof(*info)); |
100 | info->card = pcm->card->number; | 99 | info->card = pcm->card->number; |
101 | info->device = pcm->device; | 100 | info->device = pcm->device; |
@@ -370,9 +369,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, | |||
370 | unsigned int bits; | 369 | unsigned int bits; |
371 | snd_pcm_uframes_t frames; | 370 | snd_pcm_uframes_t frames; |
372 | 371 | ||
373 | snd_assert(substream != NULL, return -ENXIO); | 372 | if (PCM_RUNTIME_CHECK(substream)) |
373 | return -ENXIO; | ||
374 | runtime = substream->runtime; | 374 | runtime = substream->runtime; |
375 | snd_assert(runtime != NULL, return -ENXIO); | ||
376 | snd_pcm_stream_lock_irq(substream); | 375 | snd_pcm_stream_lock_irq(substream); |
377 | switch (runtime->status->state) { | 376 | switch (runtime->status->state) { |
378 | case SNDRV_PCM_STATE_OPEN: | 377 | case SNDRV_PCM_STATE_OPEN: |
@@ -490,9 +489,9 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) | |||
490 | struct snd_pcm_runtime *runtime; | 489 | struct snd_pcm_runtime *runtime; |
491 | int result = 0; | 490 | int result = 0; |
492 | 491 | ||
493 | snd_assert(substream != NULL, return -ENXIO); | 492 | if (PCM_RUNTIME_CHECK(substream)) |
493 | return -ENXIO; | ||
494 | runtime = substream->runtime; | 494 | runtime = substream->runtime; |
495 | snd_assert(runtime != NULL, return -ENXIO); | ||
496 | snd_pcm_stream_lock_irq(substream); | 495 | snd_pcm_stream_lock_irq(substream); |
497 | switch (runtime->status->state) { | 496 | switch (runtime->status->state) { |
498 | case SNDRV_PCM_STATE_SETUP: | 497 | case SNDRV_PCM_STATE_SETUP: |
@@ -518,9 +517,9 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream, | |||
518 | { | 517 | { |
519 | struct snd_pcm_runtime *runtime; | 518 | struct snd_pcm_runtime *runtime; |
520 | 519 | ||
521 | snd_assert(substream != NULL, return -ENXIO); | 520 | if (PCM_RUNTIME_CHECK(substream)) |
521 | return -ENXIO; | ||
522 | runtime = substream->runtime; | 522 | runtime = substream->runtime; |
523 | snd_assert(runtime != NULL, return -ENXIO); | ||
524 | snd_pcm_stream_lock_irq(substream); | 523 | snd_pcm_stream_lock_irq(substream); |
525 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { | 524 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { |
526 | snd_pcm_stream_unlock_irq(substream); | 525 | snd_pcm_stream_unlock_irq(substream); |
@@ -622,11 +621,8 @@ static int snd_pcm_status_user(struct snd_pcm_substream *substream, | |||
622 | struct snd_pcm_status __user * _status) | 621 | struct snd_pcm_status __user * _status) |
623 | { | 622 | { |
624 | struct snd_pcm_status status; | 623 | struct snd_pcm_status status; |
625 | struct snd_pcm_runtime *runtime; | ||
626 | int res; | 624 | int res; |
627 | 625 | ||
628 | snd_assert(substream != NULL, return -ENXIO); | ||
629 | runtime = substream->runtime; | ||
630 | memset(&status, 0, sizeof(status)); | 626 | memset(&status, 0, sizeof(status)); |
631 | res = snd_pcm_status(substream, &status); | 627 | res = snd_pcm_status(substream, &status); |
632 | if (res < 0) | 628 | if (res < 0) |
@@ -642,7 +638,6 @@ static int snd_pcm_channel_info(struct snd_pcm_substream *substream, | |||
642 | struct snd_pcm_runtime *runtime; | 638 | struct snd_pcm_runtime *runtime; |
643 | unsigned int channel; | 639 | unsigned int channel; |
644 | 640 | ||
645 | snd_assert(substream != NULL, return -ENXIO); | ||
646 | channel = info->channel; | 641 | channel = info->channel; |
647 | runtime = substream->runtime; | 642 | runtime = substream->runtime; |
648 | snd_pcm_stream_lock_irq(substream); | 643 | snd_pcm_stream_lock_irq(substream); |
@@ -1250,7 +1245,6 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state) | |||
1250 | int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL); | 1245 | int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL); |
1251 | if (err < 0) | 1246 | if (err < 0) |
1252 | return err; | 1247 | return err; |
1253 | // snd_assert(runtime->status->hw_ptr < runtime->buffer_size, ); | ||
1254 | runtime->hw_ptr_base = 0; | 1248 | runtime->hw_ptr_base = 0; |
1255 | runtime->hw_ptr_interrupt = runtime->status->hw_ptr - | 1249 | runtime->hw_ptr_interrupt = runtime->status->hw_ptr - |
1256 | runtime->status->hw_ptr % runtime->period_size; | 1250 | runtime->status->hw_ptr % runtime->period_size; |
@@ -1421,7 +1415,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) | |||
1421 | int i, num_drecs; | 1415 | int i, num_drecs; |
1422 | struct drain_rec *drec, drec_tmp, *d; | 1416 | struct drain_rec *drec, drec_tmp, *d; |
1423 | 1417 | ||
1424 | snd_assert(substream != NULL, return -ENXIO); | ||
1425 | card = substream->pcm->card; | 1418 | card = substream->pcm->card; |
1426 | runtime = substream->runtime; | 1419 | runtime = substream->runtime; |
1427 | 1420 | ||
@@ -1541,21 +1534,16 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream) | |||
1541 | struct snd_card *card; | 1534 | struct snd_card *card; |
1542 | int result = 0; | 1535 | int result = 0; |
1543 | 1536 | ||
1544 | snd_assert(substream != NULL, return -ENXIO); | 1537 | if (PCM_RUNTIME_CHECK(substream)) |
1538 | return -ENXIO; | ||
1545 | runtime = substream->runtime; | 1539 | runtime = substream->runtime; |
1546 | card = substream->pcm->card; | 1540 | card = substream->pcm->card; |
1547 | 1541 | ||
1548 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN || | 1542 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN || |
1549 | runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) | 1543 | runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED || |
1544 | runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) | ||
1550 | return -EBADFD; | 1545 | return -EBADFD; |
1551 | 1546 | ||
1552 | snd_power_lock(card); | ||
1553 | if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { | ||
1554 | result = snd_power_wait(card, SNDRV_CTL_POWER_D0); | ||
1555 | if (result < 0) | ||
1556 | goto _unlock; | ||
1557 | } | ||
1558 | |||
1559 | snd_pcm_stream_lock_irq(substream); | 1547 | snd_pcm_stream_lock_irq(substream); |
1560 | /* resume pause */ | 1548 | /* resume pause */ |
1561 | if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) | 1549 | if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) |
@@ -1564,8 +1552,7 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream) | |||
1564 | snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); | 1552 | snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); |
1565 | /* runtime->control->appl_ptr = runtime->status->hw_ptr; */ | 1553 | /* runtime->control->appl_ptr = runtime->status->hw_ptr; */ |
1566 | snd_pcm_stream_unlock_irq(substream); | 1554 | snd_pcm_stream_unlock_irq(substream); |
1567 | _unlock: | 1555 | |
1568 | snd_power_unlock(card); | ||
1569 | return result; | 1556 | return result; |
1570 | } | 1557 | } |
1571 | 1558 | ||
@@ -1941,33 +1928,41 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream) | |||
1941 | mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX; | 1928 | mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX; |
1942 | } | 1929 | } |
1943 | err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask); | 1930 | err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask); |
1944 | snd_assert(err >= 0, return -EINVAL); | 1931 | if (err < 0) |
1932 | return err; | ||
1945 | 1933 | ||
1946 | err = snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats); | 1934 | err = snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats); |
1947 | snd_assert(err >= 0, return -EINVAL); | 1935 | if (err < 0) |
1936 | return err; | ||
1948 | 1937 | ||
1949 | err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD); | 1938 | err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD); |
1950 | snd_assert(err >= 0, return -EINVAL); | 1939 | if (err < 0) |
1940 | return err; | ||
1951 | 1941 | ||
1952 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, | 1942 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, |
1953 | hw->channels_min, hw->channels_max); | 1943 | hw->channels_min, hw->channels_max); |
1954 | snd_assert(err >= 0, return -EINVAL); | 1944 | if (err < 0) |
1945 | return err; | ||
1955 | 1946 | ||
1956 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, | 1947 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, |
1957 | hw->rate_min, hw->rate_max); | 1948 | hw->rate_min, hw->rate_max); |
1958 | snd_assert(err >= 0, return -EINVAL); | 1949 | if (err < 0) |
1950 | return err; | ||
1959 | 1951 | ||
1960 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, | 1952 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, |
1961 | hw->period_bytes_min, hw->period_bytes_max); | 1953 | hw->period_bytes_min, hw->period_bytes_max); |
1962 | snd_assert(err >= 0, return -EINVAL); | 1954 | if (err < 0) |
1955 | return err; | ||
1963 | 1956 | ||
1964 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS, | 1957 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS, |
1965 | hw->periods_min, hw->periods_max); | 1958 | hw->periods_min, hw->periods_max); |
1966 | snd_assert(err >= 0, return -EINVAL); | 1959 | if (err < 0) |
1960 | return err; | ||
1967 | 1961 | ||
1968 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, | 1962 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, |
1969 | hw->period_bytes_min, hw->buffer_bytes_max); | 1963 | hw->period_bytes_min, hw->buffer_bytes_max); |
1970 | snd_assert(err >= 0, return -EINVAL); | 1964 | if (err < 0) |
1965 | return err; | ||
1971 | 1966 | ||
1972 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, | 1967 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, |
1973 | snd_pcm_hw_rule_buffer_bytes_max, substream, | 1968 | snd_pcm_hw_rule_buffer_bytes_max, substream, |
@@ -1978,7 +1973,8 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream) | |||
1978 | /* FIXME: remove */ | 1973 | /* FIXME: remove */ |
1979 | if (runtime->dma_bytes) { | 1974 | if (runtime->dma_bytes) { |
1980 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, runtime->dma_bytes); | 1975 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, runtime->dma_bytes); |
1981 | snd_assert(err >= 0, return -EINVAL); | 1976 | if (err < 0) |
1977 | return -EINVAL; | ||
1982 | } | 1978 | } |
1983 | 1979 | ||
1984 | if (!(hw->rates & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))) { | 1980 | if (!(hw->rates & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))) { |
@@ -2074,8 +2070,8 @@ static int snd_pcm_open_file(struct file *file, | |||
2074 | struct snd_pcm_str *str; | 2070 | struct snd_pcm_str *str; |
2075 | int err; | 2071 | int err; |
2076 | 2072 | ||
2077 | snd_assert(rpcm_file != NULL, return -EINVAL); | 2073 | if (rpcm_file) |
2078 | *rpcm_file = NULL; | 2074 | *rpcm_file = NULL; |
2079 | 2075 | ||
2080 | err = snd_pcm_open_substream(pcm, stream, file, &substream); | 2076 | err = snd_pcm_open_substream(pcm, stream, file, &substream); |
2081 | if (err < 0) | 2077 | if (err < 0) |
@@ -2093,7 +2089,8 @@ static int snd_pcm_open_file(struct file *file, | |||
2093 | substream->pcm_release = pcm_release_private; | 2089 | substream->pcm_release = pcm_release_private; |
2094 | } | 2090 | } |
2095 | file->private_data = pcm_file; | 2091 | file->private_data = pcm_file; |
2096 | *rpcm_file = pcm_file; | 2092 | if (rpcm_file) |
2093 | *rpcm_file = pcm_file; | ||
2097 | return 0; | 2094 | return 0; |
2098 | } | 2095 | } |
2099 | 2096 | ||
@@ -2177,7 +2174,8 @@ static int snd_pcm_release(struct inode *inode, struct file *file) | |||
2177 | 2174 | ||
2178 | pcm_file = file->private_data; | 2175 | pcm_file = file->private_data; |
2179 | substream = pcm_file->substream; | 2176 | substream = pcm_file->substream; |
2180 | snd_assert(substream != NULL, return -ENXIO); | 2177 | if (snd_BUG_ON(!substream)) |
2178 | return -ENXIO; | ||
2181 | pcm = substream->pcm; | 2179 | pcm = substream->pcm; |
2182 | fasync_helper(-1, file, 0, &substream->runtime->fasync); | 2180 | fasync_helper(-1, file, 0, &substream->runtime->fasync); |
2183 | mutex_lock(&pcm->open_mutex); | 2181 | mutex_lock(&pcm->open_mutex); |
@@ -2500,8 +2498,6 @@ static int snd_pcm_common_ioctl1(struct file *file, | |||
2500 | struct snd_pcm_substream *substream, | 2498 | struct snd_pcm_substream *substream, |
2501 | unsigned int cmd, void __user *arg) | 2499 | unsigned int cmd, void __user *arg) |
2502 | { | 2500 | { |
2503 | snd_assert(substream != NULL, return -ENXIO); | ||
2504 | |||
2505 | switch (cmd) { | 2501 | switch (cmd) { |
2506 | case SNDRV_PCM_IOCTL_PVERSION: | 2502 | case SNDRV_PCM_IOCTL_PVERSION: |
2507 | return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0; | 2503 | return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0; |
@@ -2570,8 +2566,10 @@ static int snd_pcm_playback_ioctl1(struct file *file, | |||
2570 | struct snd_pcm_substream *substream, | 2566 | struct snd_pcm_substream *substream, |
2571 | unsigned int cmd, void __user *arg) | 2567 | unsigned int cmd, void __user *arg) |
2572 | { | 2568 | { |
2573 | snd_assert(substream != NULL, return -ENXIO); | 2569 | if (snd_BUG_ON(!substream)) |
2574 | snd_assert(substream->stream == SNDRV_PCM_STREAM_PLAYBACK, return -EINVAL); | 2570 | return -ENXIO; |
2571 | if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_PLAYBACK)) | ||
2572 | return -EINVAL; | ||
2575 | switch (cmd) { | 2573 | switch (cmd) { |
2576 | case SNDRV_PCM_IOCTL_WRITEI_FRAMES: | 2574 | case SNDRV_PCM_IOCTL_WRITEI_FRAMES: |
2577 | { | 2575 | { |
@@ -2650,8 +2648,10 @@ static int snd_pcm_capture_ioctl1(struct file *file, | |||
2650 | struct snd_pcm_substream *substream, | 2648 | struct snd_pcm_substream *substream, |
2651 | unsigned int cmd, void __user *arg) | 2649 | unsigned int cmd, void __user *arg) |
2652 | { | 2650 | { |
2653 | snd_assert(substream != NULL, return -ENXIO); | 2651 | if (snd_BUG_ON(!substream)) |
2654 | snd_assert(substream->stream == SNDRV_PCM_STREAM_CAPTURE, return -EINVAL); | 2652 | return -ENXIO; |
2653 | if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_CAPTURE)) | ||
2654 | return -EINVAL; | ||
2655 | switch (cmd) { | 2655 | switch (cmd) { |
2656 | case SNDRV_PCM_IOCTL_READI_FRAMES: | 2656 | case SNDRV_PCM_IOCTL_READI_FRAMES: |
2657 | { | 2657 | { |
@@ -2790,7 +2790,8 @@ static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, | |||
2790 | 2790 | ||
2791 | pcm_file = file->private_data; | 2791 | pcm_file = file->private_data; |
2792 | substream = pcm_file->substream; | 2792 | substream = pcm_file->substream; |
2793 | snd_assert(substream != NULL, return -ENXIO); | 2793 | if (PCM_RUNTIME_CHECK(substream)) |
2794 | return -ENXIO; | ||
2794 | runtime = substream->runtime; | 2795 | runtime = substream->runtime; |
2795 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | 2796 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
2796 | return -EBADFD; | 2797 | return -EBADFD; |
@@ -2813,21 +2814,17 @@ static ssize_t snd_pcm_write(struct file *file, const char __user *buf, | |||
2813 | 2814 | ||
2814 | pcm_file = file->private_data; | 2815 | pcm_file = file->private_data; |
2815 | substream = pcm_file->substream; | 2816 | substream = pcm_file->substream; |
2816 | snd_assert(substream != NULL, result = -ENXIO; goto end); | 2817 | if (PCM_RUNTIME_CHECK(substream)) |
2818 | return -ENXIO; | ||
2817 | runtime = substream->runtime; | 2819 | runtime = substream->runtime; |
2818 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { | 2820 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
2819 | result = -EBADFD; | 2821 | return -EBADFD; |
2820 | goto end; | 2822 | if (!frame_aligned(runtime, count)) |
2821 | } | 2823 | return -EINVAL; |
2822 | if (!frame_aligned(runtime, count)) { | ||
2823 | result = -EINVAL; | ||
2824 | goto end; | ||
2825 | } | ||
2826 | count = bytes_to_frames(runtime, count); | 2824 | count = bytes_to_frames(runtime, count); |
2827 | result = snd_pcm_lib_write(substream, buf, count); | 2825 | result = snd_pcm_lib_write(substream, buf, count); |
2828 | if (result > 0) | 2826 | if (result > 0) |
2829 | result = frames_to_bytes(runtime, result); | 2827 | result = frames_to_bytes(runtime, result); |
2830 | end: | ||
2831 | return result; | 2828 | return result; |
2832 | } | 2829 | } |
2833 | 2830 | ||
@@ -2845,7 +2842,8 @@ static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
2845 | 2842 | ||
2846 | pcm_file = iocb->ki_filp->private_data; | 2843 | pcm_file = iocb->ki_filp->private_data; |
2847 | substream = pcm_file->substream; | 2844 | substream = pcm_file->substream; |
2848 | snd_assert(substream != NULL, return -ENXIO); | 2845 | if (PCM_RUNTIME_CHECK(substream)) |
2846 | return -ENXIO; | ||
2849 | runtime = substream->runtime; | 2847 | runtime = substream->runtime; |
2850 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | 2848 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
2851 | return -EBADFD; | 2849 | return -EBADFD; |
@@ -2879,17 +2877,14 @@ static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
2879 | 2877 | ||
2880 | pcm_file = iocb->ki_filp->private_data; | 2878 | pcm_file = iocb->ki_filp->private_data; |
2881 | substream = pcm_file->substream; | 2879 | substream = pcm_file->substream; |
2882 | snd_assert(substream != NULL, result = -ENXIO; goto end); | 2880 | if (PCM_RUNTIME_CHECK(substream)) |
2881 | return -ENXIO; | ||
2883 | runtime = substream->runtime; | 2882 | runtime = substream->runtime; |
2884 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { | 2883 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
2885 | result = -EBADFD; | 2884 | return -EBADFD; |
2886 | goto end; | ||
2887 | } | ||
2888 | if (nr_segs > 128 || nr_segs != runtime->channels || | 2885 | if (nr_segs > 128 || nr_segs != runtime->channels || |
2889 | !frame_aligned(runtime, iov->iov_len)) { | 2886 | !frame_aligned(runtime, iov->iov_len)) |
2890 | result = -EINVAL; | 2887 | return -EINVAL; |
2891 | goto end; | ||
2892 | } | ||
2893 | frames = bytes_to_samples(runtime, iov->iov_len); | 2888 | frames = bytes_to_samples(runtime, iov->iov_len); |
2894 | bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL); | 2889 | bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL); |
2895 | if (bufs == NULL) | 2890 | if (bufs == NULL) |
@@ -2900,7 +2895,6 @@ static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
2900 | if (result > 0) | 2895 | if (result > 0) |
2901 | result = frames_to_bytes(runtime, result); | 2896 | result = frames_to_bytes(runtime, result); |
2902 | kfree(bufs); | 2897 | kfree(bufs); |
2903 | end: | ||
2904 | return result; | 2898 | return result; |
2905 | } | 2899 | } |
2906 | 2900 | ||
@@ -2915,7 +2909,8 @@ static unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait) | |||
2915 | pcm_file = file->private_data; | 2909 | pcm_file = file->private_data; |
2916 | 2910 | ||
2917 | substream = pcm_file->substream; | 2911 | substream = pcm_file->substream; |
2918 | snd_assert(substream != NULL, return -ENXIO); | 2912 | if (PCM_RUNTIME_CHECK(substream)) |
2913 | return -ENXIO; | ||
2919 | runtime = substream->runtime; | 2914 | runtime = substream->runtime; |
2920 | 2915 | ||
2921 | poll_wait(file, &runtime->sleep, wait); | 2916 | poll_wait(file, &runtime->sleep, wait); |
@@ -2953,7 +2948,8 @@ static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait) | |||
2953 | pcm_file = file->private_data; | 2948 | pcm_file = file->private_data; |
2954 | 2949 | ||
2955 | substream = pcm_file->substream; | 2950 | substream = pcm_file->substream; |
2956 | snd_assert(substream != NULL, return -ENXIO); | 2951 | if (PCM_RUNTIME_CHECK(substream)) |
2952 | return -ENXIO; | ||
2957 | runtime = substream->runtime; | 2953 | runtime = substream->runtime; |
2958 | 2954 | ||
2959 | poll_wait(file, &runtime->sleep, wait); | 2955 | poll_wait(file, &runtime->sleep, wait); |
@@ -3023,7 +3019,6 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file | |||
3023 | if (!(area->vm_flags & VM_READ)) | 3019 | if (!(area->vm_flags & VM_READ)) |
3024 | return -EINVAL; | 3020 | return -EINVAL; |
3025 | runtime = substream->runtime; | 3021 | runtime = substream->runtime; |
3026 | snd_assert(runtime != NULL, return -EAGAIN); | ||
3027 | size = area->vm_end - area->vm_start; | 3022 | size = area->vm_end - area->vm_start; |
3028 | if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status))) | 3023 | if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status))) |
3029 | return -EINVAL; | 3024 | return -EINVAL; |
@@ -3063,7 +3058,6 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file | |||
3063 | if (!(area->vm_flags & VM_READ)) | 3058 | if (!(area->vm_flags & VM_READ)) |
3064 | return -EINVAL; | 3059 | return -EINVAL; |
3065 | runtime = substream->runtime; | 3060 | runtime = substream->runtime; |
3066 | snd_assert(runtime != NULL, return -EAGAIN); | ||
3067 | size = area->vm_end - area->vm_start; | 3061 | size = area->vm_end - area->vm_start; |
3068 | if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))) | 3062 | if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))) |
3069 | return -EINVAL; | 3063 | return -EINVAL; |
@@ -3195,7 +3189,6 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, | |||
3195 | return -EINVAL; | 3189 | return -EINVAL; |
3196 | } | 3190 | } |
3197 | runtime = substream->runtime; | 3191 | runtime = substream->runtime; |
3198 | snd_assert(runtime != NULL, return -EAGAIN); | ||
3199 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | 3192 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
3200 | return -EBADFD; | 3193 | return -EBADFD; |
3201 | if (!(runtime->info & SNDRV_PCM_INFO_MMAP)) | 3194 | if (!(runtime->info & SNDRV_PCM_INFO_MMAP)) |
@@ -3227,7 +3220,8 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) | |||
3227 | 3220 | ||
3228 | pcm_file = file->private_data; | 3221 | pcm_file = file->private_data; |
3229 | substream = pcm_file->substream; | 3222 | substream = pcm_file->substream; |
3230 | snd_assert(substream != NULL, return -ENXIO); | 3223 | if (PCM_RUNTIME_CHECK(substream)) |
3224 | return -ENXIO; | ||
3231 | 3225 | ||
3232 | offset = area->vm_pgoff << PAGE_SHIFT; | 3226 | offset = area->vm_pgoff << PAGE_SHIFT; |
3233 | switch (offset) { | 3227 | switch (offset) { |
@@ -3255,9 +3249,9 @@ static int snd_pcm_fasync(int fd, struct file * file, int on) | |||
3255 | lock_kernel(); | 3249 | lock_kernel(); |
3256 | pcm_file = file->private_data; | 3250 | pcm_file = file->private_data; |
3257 | substream = pcm_file->substream; | 3251 | substream = pcm_file->substream; |
3258 | snd_assert(substream != NULL, goto out); | 3252 | if (PCM_RUNTIME_CHECK(substream)) |
3253 | goto out; | ||
3259 | runtime = substream->runtime; | 3254 | runtime = substream->runtime; |
3260 | |||
3261 | err = fasync_helper(fd, file, on, &runtime->fasync); | 3255 | err = fasync_helper(fd, file, on, &runtime->fasync); |
3262 | out: | 3256 | out: |
3263 | unlock_kernel(); | 3257 | unlock_kernel(); |
@@ -3391,6 +3385,17 @@ out: | |||
3391 | } | 3385 | } |
3392 | #endif /* CONFIG_SND_SUPPORT_OLD_API */ | 3386 | #endif /* CONFIG_SND_SUPPORT_OLD_API */ |
3393 | 3387 | ||
3388 | #ifndef CONFIG_MMU | ||
3389 | unsigned long dummy_get_unmapped_area(struct file *file, unsigned long addr, | ||
3390 | unsigned long len, unsigned long pgoff, | ||
3391 | unsigned long flags) | ||
3392 | { | ||
3393 | return 0; | ||
3394 | } | ||
3395 | #else | ||
3396 | # define dummy_get_unmapped_area NULL | ||
3397 | #endif | ||
3398 | |||
3394 | /* | 3399 | /* |
3395 | * Register section | 3400 | * Register section |
3396 | */ | 3401 | */ |
@@ -3407,6 +3412,7 @@ const struct file_operations snd_pcm_f_ops[2] = { | |||
3407 | .compat_ioctl = snd_pcm_ioctl_compat, | 3412 | .compat_ioctl = snd_pcm_ioctl_compat, |
3408 | .mmap = snd_pcm_mmap, | 3413 | .mmap = snd_pcm_mmap, |
3409 | .fasync = snd_pcm_fasync, | 3414 | .fasync = snd_pcm_fasync, |
3415 | .get_unmapped_area = dummy_get_unmapped_area, | ||
3410 | }, | 3416 | }, |
3411 | { | 3417 | { |
3412 | .owner = THIS_MODULE, | 3418 | .owner = THIS_MODULE, |
@@ -3419,5 +3425,6 @@ const struct file_operations snd_pcm_f_ops[2] = { | |||
3419 | .compat_ioctl = snd_pcm_ioctl_compat, | 3425 | .compat_ioctl = snd_pcm_ioctl_compat, |
3420 | .mmap = snd_pcm_mmap, | 3426 | .mmap = snd_pcm_mmap, |
3421 | .fasync = snd_pcm_fasync, | 3427 | .fasync = snd_pcm_fasync, |
3428 | .get_unmapped_area = dummy_get_unmapped_area, | ||
3422 | } | 3429 | } |
3423 | }; | 3430 | }; |