diff options
author | Takashi Iwai <tiwai@suse.de> | 2006-03-27 09:40:49 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-03-31 10:58:59 -0500 |
commit | 3bf75f9b90c981f18f27a0d35a44f488ab68c8ea (patch) | |
tree | 9284c90f09ce38fc3bb2ebc46624ddf3db09b526 /sound/core/oss | |
parent | bf1bbb5a49eec51c30d341606885507b501b37e8 (diff) |
[ALSA] Clean up PCM codes (take 2)
- Clean up initialization and destruction of substream instance
Now snd_pcm_open_substream() alone does most initialization jobs.
Add pcm_release callback for cleaning up at snd_pcm_release_substream()
- Tidy up PCM oss code
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core/oss')
-rw-r--r-- | sound/core/oss/pcm_oss.c | 151 |
1 files changed, 44 insertions, 107 deletions
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 54be0bba6bd2..c056cbfe5519 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
@@ -1671,6 +1671,18 @@ static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, | |||
1671 | return NULL; | 1671 | return NULL; |
1672 | } | 1672 | } |
1673 | 1673 | ||
1674 | static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream) | ||
1675 | { | ||
1676 | struct snd_pcm_runtime *runtime; | ||
1677 | runtime = substream->runtime; | ||
1678 | vfree(runtime->oss.buffer); | ||
1679 | runtime->oss.buffer = NULL; | ||
1680 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
1681 | snd_pcm_oss_plugin_clear(substream); | ||
1682 | #endif | ||
1683 | substream->oss.oss = 0; | ||
1684 | } | ||
1685 | |||
1674 | static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, | 1686 | static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, |
1675 | struct snd_pcm_oss_setup *setup, | 1687 | struct snd_pcm_oss_setup *setup, |
1676 | int minor) | 1688 | int minor) |
@@ -1679,6 +1691,10 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, | |||
1679 | 1691 | ||
1680 | substream->oss.oss = 1; | 1692 | substream->oss.oss = 1; |
1681 | substream->oss.setup = setup; | 1693 | substream->oss.setup = setup; |
1694 | if (setup->nonblock) | ||
1695 | substream->ffile->f_flags |= O_NONBLOCK; | ||
1696 | else | ||
1697 | substream->ffile->f_flags &= ~O_NONBLOCK; | ||
1682 | runtime = substream->runtime; | 1698 | runtime = substream->runtime; |
1683 | runtime->oss.params = 1; | 1699 | runtime->oss.params = 1; |
1684 | runtime->oss.trigger = 1; | 1700 | runtime->oss.trigger = 1; |
@@ -1697,18 +1713,7 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, | |||
1697 | runtime->oss.fragshift = 0; | 1713 | runtime->oss.fragshift = 0; |
1698 | runtime->oss.maxfrags = 0; | 1714 | runtime->oss.maxfrags = 0; |
1699 | runtime->oss.subdivision = 0; | 1715 | runtime->oss.subdivision = 0; |
1700 | } | 1716 | substream->pcm_release = snd_pcm_oss_release_substream; |
1701 | |||
1702 | static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream) | ||
1703 | { | ||
1704 | struct snd_pcm_runtime *runtime; | ||
1705 | runtime = substream->runtime; | ||
1706 | vfree(runtime->oss.buffer); | ||
1707 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
1708 | snd_pcm_oss_plugin_clear(substream); | ||
1709 | #endif | ||
1710 | substream->oss.file = NULL; | ||
1711 | substream->oss.oss = 0; | ||
1712 | } | 1717 | } |
1713 | 1718 | ||
1714 | static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) | 1719 | static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) |
@@ -1717,23 +1722,8 @@ static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) | |||
1717 | snd_assert(pcm_oss_file != NULL, return -ENXIO); | 1722 | snd_assert(pcm_oss_file != NULL, return -ENXIO); |
1718 | for (cidx = 0; cidx < 2; ++cidx) { | 1723 | for (cidx = 0; cidx < 2; ++cidx) { |
1719 | struct snd_pcm_substream *substream = pcm_oss_file->streams[cidx]; | 1724 | struct snd_pcm_substream *substream = pcm_oss_file->streams[cidx]; |
1720 | struct snd_pcm_runtime *runtime; | 1725 | if (substream) |
1721 | if (substream == NULL) | 1726 | snd_pcm_release_substream(substream); |
1722 | continue; | ||
1723 | runtime = substream->runtime; | ||
1724 | |||
1725 | snd_pcm_stream_lock_irq(substream); | ||
1726 | if (snd_pcm_running(substream)) | ||
1727 | snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); | ||
1728 | snd_pcm_stream_unlock_irq(substream); | ||
1729 | if (substream->ffile != NULL) { | ||
1730 | if (substream->ops->hw_free != NULL) | ||
1731 | substream->ops->hw_free(substream); | ||
1732 | substream->ops->close(substream); | ||
1733 | substream->ffile = NULL; | ||
1734 | } | ||
1735 | snd_pcm_oss_release_substream(substream); | ||
1736 | snd_pcm_release_substream(substream); | ||
1737 | } | 1727 | } |
1738 | kfree(pcm_oss_file); | 1728 | kfree(pcm_oss_file); |
1739 | return 0; | 1729 | return 0; |
@@ -1743,12 +1733,11 @@ static int snd_pcm_oss_open_file(struct file *file, | |||
1743 | struct snd_pcm *pcm, | 1733 | struct snd_pcm *pcm, |
1744 | struct snd_pcm_oss_file **rpcm_oss_file, | 1734 | struct snd_pcm_oss_file **rpcm_oss_file, |
1745 | int minor, | 1735 | int minor, |
1746 | struct snd_pcm_oss_setup *psetup, | 1736 | struct snd_pcm_oss_setup **setup) |
1747 | struct snd_pcm_oss_setup *csetup) | ||
1748 | { | 1737 | { |
1749 | int err = 0; | 1738 | int idx, err; |
1750 | struct snd_pcm_oss_file *pcm_oss_file; | 1739 | struct snd_pcm_oss_file *pcm_oss_file; |
1751 | struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL; | 1740 | struct snd_pcm_substream *substream; |
1752 | unsigned int f_mode = file->f_mode; | 1741 | unsigned int f_mode = file->f_mode; |
1753 | 1742 | ||
1754 | snd_assert(rpcm_oss_file != NULL, return -EINVAL); | 1743 | snd_assert(rpcm_oss_file != NULL, return -EINVAL); |
@@ -1761,73 +1750,31 @@ static int snd_pcm_oss_open_file(struct file *file, | |||
1761 | if ((f_mode & (FMODE_WRITE|FMODE_READ)) == (FMODE_WRITE|FMODE_READ) && | 1750 | if ((f_mode & (FMODE_WRITE|FMODE_READ)) == (FMODE_WRITE|FMODE_READ) && |
1762 | (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX)) | 1751 | (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX)) |
1763 | f_mode = FMODE_WRITE; | 1752 | f_mode = FMODE_WRITE; |
1764 | if ((f_mode & FMODE_WRITE) && !(psetup && psetup->disable)) { | 1753 | |
1765 | if ((err = snd_pcm_open_substream(pcm, SNDRV_PCM_STREAM_PLAYBACK, | 1754 | for (idx = 0; idx < 2; idx++) { |
1766 | &psubstream)) < 0) { | 1755 | if (! setup[idx] || setup[idx]->disable) |
1756 | continue; | ||
1757 | if (idx == SNDRV_PCM_STREAM_PLAYBACK) { | ||
1758 | if (! (f_mode & FMODE_WRITE)) | ||
1759 | continue; | ||
1760 | } else { | ||
1761 | if (! (f_mode & FMODE_READ)) | ||
1762 | continue; | ||
1763 | } | ||
1764 | err = snd_pcm_open_substream(pcm, idx, file, &substream); | ||
1765 | if (err < 0) { | ||
1767 | snd_pcm_oss_release_file(pcm_oss_file); | 1766 | snd_pcm_oss_release_file(pcm_oss_file); |
1768 | return err; | 1767 | return err; |
1769 | } | 1768 | } |
1770 | pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK] = psubstream; | 1769 | |
1771 | } | 1770 | pcm_oss_file->streams[idx] = substream; |
1772 | if ((f_mode & FMODE_READ) && !(csetup && csetup->disable)) { | 1771 | snd_pcm_oss_init_substream(substream, setup[idx], minor); |
1773 | if ((err = snd_pcm_open_substream(pcm, SNDRV_PCM_STREAM_CAPTURE, | ||
1774 | &csubstream)) < 0) { | ||
1775 | if (!(f_mode & FMODE_WRITE) || err != -ENODEV) { | ||
1776 | snd_pcm_oss_release_file(pcm_oss_file); | ||
1777 | return err; | ||
1778 | } else { | ||
1779 | csubstream = NULL; | ||
1780 | } | ||
1781 | } | ||
1782 | pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE] = csubstream; | ||
1783 | } | 1772 | } |
1784 | 1773 | ||
1785 | if (psubstream == NULL && csubstream == NULL) { | 1774 | if (! pcm_oss_file->streams[0] && pcm_oss_file->streams[1]) { |
1786 | snd_pcm_oss_release_file(pcm_oss_file); | 1775 | snd_pcm_oss_release_file(pcm_oss_file); |
1787 | return -EINVAL; | 1776 | return -EINVAL; |
1788 | } | 1777 | } |
1789 | if (psubstream != NULL) { | ||
1790 | psubstream->oss.file = pcm_oss_file; | ||
1791 | err = snd_pcm_hw_constraints_init(psubstream); | ||
1792 | if (err < 0) { | ||
1793 | snd_printd("snd_pcm_hw_constraint_init failed\n"); | ||
1794 | snd_pcm_oss_release_file(pcm_oss_file); | ||
1795 | return err; | ||
1796 | } | ||
1797 | if ((err = psubstream->ops->open(psubstream)) < 0) { | ||
1798 | snd_pcm_oss_release_file(pcm_oss_file); | ||
1799 | return err; | ||
1800 | } | ||
1801 | psubstream->ffile = file; | ||
1802 | err = snd_pcm_hw_constraints_complete(psubstream); | ||
1803 | if (err < 0) { | ||
1804 | snd_printd("snd_pcm_hw_constraint_complete failed\n"); | ||
1805 | snd_pcm_oss_release_file(pcm_oss_file); | ||
1806 | return err; | ||
1807 | } | ||
1808 | snd_pcm_oss_init_substream(psubstream, psetup, minor); | ||
1809 | } | ||
1810 | if (csubstream != NULL) { | ||
1811 | csubstream->oss.file = pcm_oss_file; | ||
1812 | err = snd_pcm_hw_constraints_init(csubstream); | ||
1813 | if (err < 0) { | ||
1814 | snd_printd("snd_pcm_hw_constraint_init failed\n"); | ||
1815 | snd_pcm_oss_release_file(pcm_oss_file); | ||
1816 | return err; | ||
1817 | } | ||
1818 | if ((err = csubstream->ops->open(csubstream)) < 0) { | ||
1819 | snd_pcm_oss_release_file(pcm_oss_file); | ||
1820 | return err; | ||
1821 | } | ||
1822 | csubstream->ffile = file; | ||
1823 | err = snd_pcm_hw_constraints_complete(csubstream); | ||
1824 | if (err < 0) { | ||
1825 | snd_printd("snd_pcm_hw_constraint_complete failed\n"); | ||
1826 | snd_pcm_oss_release_file(pcm_oss_file); | ||
1827 | return err; | ||
1828 | } | ||
1829 | snd_pcm_oss_init_substream(csubstream, csetup, minor); | ||
1830 | } | ||
1831 | 1778 | ||
1832 | file->private_data = pcm_oss_file; | 1779 | file->private_data = pcm_oss_file; |
1833 | *rpcm_oss_file = pcm_oss_file; | 1780 | *rpcm_oss_file = pcm_oss_file; |
@@ -1852,7 +1799,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) | |||
1852 | char task_name[32]; | 1799 | char task_name[32]; |
1853 | struct snd_pcm *pcm; | 1800 | struct snd_pcm *pcm; |
1854 | struct snd_pcm_oss_file *pcm_oss_file; | 1801 | struct snd_pcm_oss_file *pcm_oss_file; |
1855 | struct snd_pcm_oss_setup *psetup = NULL, *csetup = NULL; | 1802 | struct snd_pcm_oss_setup *setup[2]; |
1856 | int nonblock; | 1803 | int nonblock; |
1857 | wait_queue_t wait; | 1804 | wait_queue_t wait; |
1858 | 1805 | ||
@@ -1873,23 +1820,13 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) | |||
1873 | err = -EFAULT; | 1820 | err = -EFAULT; |
1874 | goto __error; | 1821 | goto __error; |
1875 | } | 1822 | } |
1823 | memset(setup, 0, sizeof(*setup)); | ||
1876 | if (file->f_mode & FMODE_WRITE) | 1824 | if (file->f_mode & FMODE_WRITE) |
1877 | psetup = snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_PLAYBACK, task_name); | 1825 | setup[0] = snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_PLAYBACK, task_name); |
1878 | if (file->f_mode & FMODE_READ) | 1826 | if (file->f_mode & FMODE_READ) |
1879 | csetup = snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_CAPTURE, task_name); | 1827 | setup[1] = snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_CAPTURE, task_name); |
1880 | 1828 | ||
1881 | nonblock = !!(file->f_flags & O_NONBLOCK); | 1829 | nonblock = !!(file->f_flags & O_NONBLOCK); |
1882 | if (psetup && !psetup->disable) { | ||
1883 | if (psetup->nonblock) | ||
1884 | nonblock = 1; | ||
1885 | else if (psetup->block) | ||
1886 | nonblock = 0; | ||
1887 | } else if (csetup && !csetup->disable) { | ||
1888 | if (csetup->nonblock) | ||
1889 | nonblock = 1; | ||
1890 | else if (csetup->block) | ||
1891 | nonblock = 0; | ||
1892 | } | ||
1893 | if (!nonblock) | 1830 | if (!nonblock) |
1894 | nonblock = nonblock_open; | 1831 | nonblock = nonblock_open; |
1895 | 1832 | ||
@@ -1898,7 +1835,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) | |||
1898 | mutex_lock(&pcm->open_mutex); | 1835 | mutex_lock(&pcm->open_mutex); |
1899 | while (1) { | 1836 | while (1) { |
1900 | err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file, | 1837 | err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file, |
1901 | iminor(inode), psetup, csetup); | 1838 | iminor(inode), setup); |
1902 | if (err >= 0) | 1839 | if (err >= 0) |
1903 | break; | 1840 | break; |
1904 | if (err == -EAGAIN) { | 1841 | if (err == -EAGAIN) { |