aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/pcm_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/pcm_lib.c')
-rw-r--r--sound/core/pcm_lib.c102
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,
380int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) 381int 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
424static int snd_interval_refine_first(struct snd_interval *i) 426static 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
436static int snd_interval_refine_last(struct snd_interval *i) 439static 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
1672snd_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 */
1683static 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
1696snd_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