diff options
Diffstat (limited to 'sound/core/pcm_lib.c')
-rw-r--r-- | sound/core/pcm_lib.c | 102 |
1 files changed, 61 insertions, 41 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 1533f0379e9d..6ea5cfb83998 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -85,7 +85,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram | |||
85 | } | 85 | } |
86 | frames = runtime->buffer_size - runtime->silence_filled; | 86 | frames = runtime->buffer_size - runtime->silence_filled; |
87 | } | 87 | } |
88 | snd_assert(frames <= runtime->buffer_size, return); | 88 | if (snd_BUG_ON(frames > runtime->buffer_size)) |
89 | return; | ||
89 | if (frames == 0) | 90 | if (frames == 0) |
90 | return; | 91 | return; |
91 | ofs = runtime->silence_start % runtime->buffer_size; | 92 | ofs = runtime->silence_start % runtime->buffer_size; |
@@ -96,7 +97,7 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram | |||
96 | if (substream->ops->silence) { | 97 | if (substream->ops->silence) { |
97 | int err; | 98 | int err; |
98 | err = substream->ops->silence(substream, -1, ofs, transfer); | 99 | err = substream->ops->silence(substream, -1, ofs, transfer); |
99 | snd_assert(err >= 0, ); | 100 | snd_BUG_ON(err < 0); |
100 | } else { | 101 | } else { |
101 | char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs); | 102 | char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs); |
102 | snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels); | 103 | snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels); |
@@ -108,7 +109,7 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram | |||
108 | for (c = 0; c < channels; ++c) { | 109 | for (c = 0; c < channels; ++c) { |
109 | int err; | 110 | int err; |
110 | err = substream->ops->silence(substream, c, ofs, transfer); | 111 | err = substream->ops->silence(substream, c, ofs, transfer); |
111 | snd_assert(err >= 0, ); | 112 | snd_BUG_ON(err < 0); |
112 | } | 113 | } |
113 | } else { | 114 | } else { |
114 | size_t dma_csize = runtime->dma_bytes / channels; | 115 | size_t dma_csize = runtime->dma_bytes / channels; |
@@ -354,7 +355,7 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b, | |||
354 | { | 355 | { |
355 | u_int64_t n = (u_int64_t) a * b; | 356 | u_int64_t n = (u_int64_t) a * b; |
356 | if (c == 0) { | 357 | if (c == 0) { |
357 | snd_assert(n > 0, ); | 358 | snd_BUG_ON(!n); |
358 | *r = 0; | 359 | *r = 0; |
359 | return UINT_MAX; | 360 | return UINT_MAX; |
360 | } | 361 | } |
@@ -380,7 +381,8 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b, | |||
380 | int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) | 381 | int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) |
381 | { | 382 | { |
382 | int changed = 0; | 383 | int changed = 0; |
383 | snd_assert(!snd_interval_empty(i), return -EINVAL); | 384 | if (snd_BUG_ON(snd_interval_empty(i))) |
385 | return -EINVAL; | ||
384 | if (i->min < v->min) { | 386 | if (i->min < v->min) { |
385 | i->min = v->min; | 387 | i->min = v->min; |
386 | i->openmin = v->openmin; | 388 | i->openmin = v->openmin; |
@@ -423,7 +425,8 @@ EXPORT_SYMBOL(snd_interval_refine); | |||
423 | 425 | ||
424 | static int snd_interval_refine_first(struct snd_interval *i) | 426 | static int snd_interval_refine_first(struct snd_interval *i) |
425 | { | 427 | { |
426 | snd_assert(!snd_interval_empty(i), return -EINVAL); | 428 | if (snd_BUG_ON(snd_interval_empty(i))) |
429 | return -EINVAL; | ||
427 | if (snd_interval_single(i)) | 430 | if (snd_interval_single(i)) |
428 | return 0; | 431 | return 0; |
429 | i->max = i->min; | 432 | i->max = i->min; |
@@ -435,7 +438,8 @@ static int snd_interval_refine_first(struct snd_interval *i) | |||
435 | 438 | ||
436 | static int snd_interval_refine_last(struct snd_interval *i) | 439 | static int snd_interval_refine_last(struct snd_interval *i) |
437 | { | 440 | { |
438 | snd_assert(!snd_interval_empty(i), return -EINVAL); | 441 | if (snd_BUG_ON(snd_interval_empty(i))) |
442 | return -EINVAL; | ||
439 | if (snd_interval_single(i)) | 443 | if (snd_interval_single(i)) |
440 | return 0; | 444 | return 0; |
441 | i->min = i->max; | 445 | i->min = i->max; |
@@ -889,7 +893,8 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, | |||
889 | c->private = private; | 893 | c->private = private; |
890 | k = 0; | 894 | k = 0; |
891 | while (1) { | 895 | while (1) { |
892 | snd_assert(k < ARRAY_SIZE(c->deps), return -EINVAL); | 896 | if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) |
897 | return -EINVAL; | ||
893 | c->deps[k++] = dep; | 898 | c->deps[k++] = dep; |
894 | if (dep < 0) | 899 | if (dep < 0) |
895 | break; | 900 | break; |
@@ -1285,7 +1290,8 @@ int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, | |||
1285 | return changed; | 1290 | return changed; |
1286 | if (params->rmask) { | 1291 | if (params->rmask) { |
1287 | int err = snd_pcm_hw_refine(pcm, params); | 1292 | int err = snd_pcm_hw_refine(pcm, params); |
1288 | snd_assert(err >= 0, return err); | 1293 | if (snd_BUG_ON(err < 0)) |
1294 | return err; | ||
1289 | } | 1295 | } |
1290 | return snd_pcm_hw_param_value(params, var, dir); | 1296 | return snd_pcm_hw_param_value(params, var, dir); |
1291 | } | 1297 | } |
@@ -1330,7 +1336,8 @@ int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, | |||
1330 | return changed; | 1336 | return changed; |
1331 | if (params->rmask) { | 1337 | if (params->rmask) { |
1332 | int err = snd_pcm_hw_refine(pcm, params); | 1338 | int err = snd_pcm_hw_refine(pcm, params); |
1333 | snd_assert(err >= 0, return err); | 1339 | if (snd_BUG_ON(err < 0)) |
1340 | return err; | ||
1334 | } | 1341 | } |
1335 | return snd_pcm_hw_param_value(params, var, dir); | 1342 | return snd_pcm_hw_param_value(params, var, dir); |
1336 | } | 1343 | } |
@@ -1368,7 +1375,8 @@ int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, | |||
1368 | err = snd_pcm_hw_param_first(pcm, params, *v, NULL); | 1375 | err = snd_pcm_hw_param_first(pcm, params, *v, NULL); |
1369 | else | 1376 | else |
1370 | err = snd_pcm_hw_param_last(pcm, params, *v, NULL); | 1377 | err = snd_pcm_hw_param_last(pcm, params, *v, NULL); |
1371 | snd_assert(err >= 0, return err); | 1378 | if (snd_BUG_ON(err < 0)) |
1379 | return err; | ||
1372 | } | 1380 | } |
1373 | return 0; | 1381 | return 0; |
1374 | } | 1382 | } |
@@ -1466,9 +1474,9 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream) | |||
1466 | struct snd_pcm_runtime *runtime; | 1474 | struct snd_pcm_runtime *runtime; |
1467 | unsigned long flags; | 1475 | unsigned long flags; |
1468 | 1476 | ||
1469 | snd_assert(substream != NULL, return); | 1477 | if (PCM_RUNTIME_CHECK(substream)) |
1478 | return; | ||
1470 | runtime = substream->runtime; | 1479 | runtime = substream->runtime; |
1471 | snd_assert(runtime != NULL, return); | ||
1472 | 1480 | ||
1473 | if (runtime->transfer_ack_begin) | 1481 | if (runtime->transfer_ack_begin) |
1474 | runtime->transfer_ack_begin(substream); | 1482 | runtime->transfer_ack_begin(substream); |
@@ -1567,7 +1575,6 @@ static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, | |||
1567 | return err; | 1575 | return err; |
1568 | } else { | 1576 | } else { |
1569 | char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); | 1577 | char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); |
1570 | snd_assert(runtime->dma_area, return -EFAULT); | ||
1571 | if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames))) | 1578 | if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames))) |
1572 | return -EFAULT; | 1579 | return -EFAULT; |
1573 | } | 1580 | } |
@@ -1629,7 +1636,10 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, | |||
1629 | cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; | 1636 | cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; |
1630 | if (frames > cont) | 1637 | if (frames > cont) |
1631 | frames = cont; | 1638 | frames = cont; |
1632 | snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL); | 1639 | if (snd_BUG_ON(!frames)) { |
1640 | snd_pcm_stream_unlock_irq(substream); | ||
1641 | return -EINVAL; | ||
1642 | } | ||
1633 | appl_ptr = runtime->control->appl_ptr; | 1643 | appl_ptr = runtime->control->appl_ptr; |
1634 | appl_ofs = appl_ptr % runtime->buffer_size; | 1644 | appl_ofs = appl_ptr % runtime->buffer_size; |
1635 | snd_pcm_stream_unlock_irq(substream); | 1645 | snd_pcm_stream_unlock_irq(substream); |
@@ -1669,18 +1679,30 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, | |||
1669 | return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; | 1679 | return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; |
1670 | } | 1680 | } |
1671 | 1681 | ||
1672 | snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size) | 1682 | /* sanity-check for read/write methods */ |
1683 | static int pcm_sanity_check(struct snd_pcm_substream *substream) | ||
1673 | { | 1684 | { |
1674 | struct snd_pcm_runtime *runtime; | 1685 | struct snd_pcm_runtime *runtime; |
1675 | int nonblock; | 1686 | if (PCM_RUNTIME_CHECK(substream)) |
1676 | 1687 | return -ENXIO; | |
1677 | snd_assert(substream != NULL, return -ENXIO); | ||
1678 | runtime = substream->runtime; | 1688 | runtime = substream->runtime; |
1679 | snd_assert(runtime != NULL, return -ENXIO); | 1689 | if (snd_BUG_ON(!substream->ops->copy && !runtime->dma_area)) |
1680 | snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); | 1690 | return -EINVAL; |
1681 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | 1691 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
1682 | return -EBADFD; | 1692 | return -EBADFD; |
1693 | return 0; | ||
1694 | } | ||
1695 | |||
1696 | snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size) | ||
1697 | { | ||
1698 | struct snd_pcm_runtime *runtime; | ||
1699 | int nonblock; | ||
1700 | int err; | ||
1683 | 1701 | ||
1702 | err = pcm_sanity_check(substream); | ||
1703 | if (err < 0) | ||
1704 | return err; | ||
1705 | runtime = substream->runtime; | ||
1684 | nonblock = !!(substream->f_flags & O_NONBLOCK); | 1706 | nonblock = !!(substream->f_flags & O_NONBLOCK); |
1685 | 1707 | ||
1686 | if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && | 1708 | if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && |
@@ -1703,7 +1725,8 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, | |||
1703 | int channels = runtime->channels; | 1725 | int channels = runtime->channels; |
1704 | int c; | 1726 | int c; |
1705 | if (substream->ops->copy) { | 1727 | if (substream->ops->copy) { |
1706 | snd_assert(substream->ops->silence != NULL, return -EINVAL); | 1728 | if (snd_BUG_ON(!substream->ops->silence)) |
1729 | return -EINVAL; | ||
1707 | for (c = 0; c < channels; ++c, ++bufs) { | 1730 | for (c = 0; c < channels; ++c, ++bufs) { |
1708 | if (*bufs == NULL) { | 1731 | if (*bufs == NULL) { |
1709 | if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0) | 1732 | if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0) |
@@ -1717,7 +1740,6 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, | |||
1717 | } else { | 1740 | } else { |
1718 | /* default transfer behaviour */ | 1741 | /* default transfer behaviour */ |
1719 | size_t dma_csize = runtime->dma_bytes / channels; | 1742 | size_t dma_csize = runtime->dma_bytes / channels; |
1720 | snd_assert(runtime->dma_area, return -EFAULT); | ||
1721 | for (c = 0; c < channels; ++c, ++bufs) { | 1743 | for (c = 0; c < channels; ++c, ++bufs) { |
1722 | char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); | 1744 | char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); |
1723 | if (*bufs == NULL) { | 1745 | if (*bufs == NULL) { |
@@ -1738,14 +1760,12 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream, | |||
1738 | { | 1760 | { |
1739 | struct snd_pcm_runtime *runtime; | 1761 | struct snd_pcm_runtime *runtime; |
1740 | int nonblock; | 1762 | int nonblock; |
1763 | int err; | ||
1741 | 1764 | ||
1742 | snd_assert(substream != NULL, return -ENXIO); | 1765 | err = pcm_sanity_check(substream); |
1766 | if (err < 0) | ||
1767 | return err; | ||
1743 | runtime = substream->runtime; | 1768 | runtime = substream->runtime; |
1744 | snd_assert(runtime != NULL, return -ENXIO); | ||
1745 | snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); | ||
1746 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | ||
1747 | return -EBADFD; | ||
1748 | |||
1749 | nonblock = !!(substream->f_flags & O_NONBLOCK); | 1769 | nonblock = !!(substream->f_flags & O_NONBLOCK); |
1750 | 1770 | ||
1751 | if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) | 1771 | if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) |
@@ -1769,7 +1789,6 @@ static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, | |||
1769 | return err; | 1789 | return err; |
1770 | } else { | 1790 | } else { |
1771 | char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); | 1791 | char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); |
1772 | snd_assert(runtime->dma_area, return -EFAULT); | ||
1773 | if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames))) | 1792 | if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames))) |
1774 | return -EFAULT; | 1793 | return -EFAULT; |
1775 | } | 1794 | } |
@@ -1841,7 +1860,10 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, | |||
1841 | cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; | 1860 | cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; |
1842 | if (frames > cont) | 1861 | if (frames > cont) |
1843 | frames = cont; | 1862 | frames = cont; |
1844 | snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL); | 1863 | if (snd_BUG_ON(!frames)) { |
1864 | snd_pcm_stream_unlock_irq(substream); | ||
1865 | return -EINVAL; | ||
1866 | } | ||
1845 | appl_ptr = runtime->control->appl_ptr; | 1867 | appl_ptr = runtime->control->appl_ptr; |
1846 | appl_ofs = appl_ptr % runtime->buffer_size; | 1868 | appl_ofs = appl_ptr % runtime->buffer_size; |
1847 | snd_pcm_stream_unlock_irq(substream); | 1869 | snd_pcm_stream_unlock_irq(substream); |
@@ -1879,14 +1901,12 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u | |||
1879 | { | 1901 | { |
1880 | struct snd_pcm_runtime *runtime; | 1902 | struct snd_pcm_runtime *runtime; |
1881 | int nonblock; | 1903 | int nonblock; |
1904 | int err; | ||
1882 | 1905 | ||
1883 | snd_assert(substream != NULL, return -ENXIO); | 1906 | err = pcm_sanity_check(substream); |
1907 | if (err < 0) | ||
1908 | return err; | ||
1884 | runtime = substream->runtime; | 1909 | runtime = substream->runtime; |
1885 | snd_assert(runtime != NULL, return -ENXIO); | ||
1886 | snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); | ||
1887 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | ||
1888 | return -EBADFD; | ||
1889 | |||
1890 | nonblock = !!(substream->f_flags & O_NONBLOCK); | 1910 | nonblock = !!(substream->f_flags & O_NONBLOCK); |
1891 | if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) | 1911 | if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) |
1892 | return -EINVAL; | 1912 | return -EINVAL; |
@@ -1916,7 +1936,6 @@ static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, | |||
1916 | } | 1936 | } |
1917 | } else { | 1937 | } else { |
1918 | snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels; | 1938 | snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels; |
1919 | snd_assert(runtime->dma_area, return -EFAULT); | ||
1920 | for (c = 0; c < channels; ++c, ++bufs) { | 1939 | for (c = 0; c < channels; ++c, ++bufs) { |
1921 | char *hwbuf; | 1940 | char *hwbuf; |
1922 | char __user *buf; | 1941 | char __user *buf; |
@@ -1938,11 +1957,12 @@ snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream, | |||
1938 | { | 1957 | { |
1939 | struct snd_pcm_runtime *runtime; | 1958 | struct snd_pcm_runtime *runtime; |
1940 | int nonblock; | 1959 | int nonblock; |
1960 | int err; | ||
1941 | 1961 | ||
1942 | snd_assert(substream != NULL, return -ENXIO); | 1962 | err = pcm_sanity_check(substream); |
1963 | if (err < 0) | ||
1964 | return err; | ||
1943 | runtime = substream->runtime; | 1965 | runtime = substream->runtime; |
1944 | snd_assert(runtime != NULL, return -ENXIO); | ||
1945 | snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); | ||
1946 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | 1966 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
1947 | return -EBADFD; | 1967 | return -EBADFD; |
1948 | 1968 | ||