aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/oss/pcm_oss.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/oss/pcm_oss.c')
-rw-r--r--sound/core/oss/pcm_oss.c101
1 files changed, 24 insertions, 77 deletions
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index cd8b7bef8d06..e49f448ee04f 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -67,18 +67,6 @@ static int snd_pcm_oss_get_rate(struct snd_pcm_oss_file *pcm_oss_file);
67static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file); 67static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file);
68static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file); 68static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file);
69 69
70static inline mm_segment_t snd_enter_user(void)
71{
72 mm_segment_t fs = get_fs();
73 set_fs(get_ds());
74 return fs;
75}
76
77static inline void snd_leave_user(mm_segment_t fs)
78{
79 set_fs(fs);
80}
81
82/* 70/*
83 * helper functions to process hw_params 71 * helper functions to process hw_params
84 */ 72 */
@@ -799,7 +787,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
799static int choose_rate(struct snd_pcm_substream *substream, 787static int choose_rate(struct snd_pcm_substream *substream,
800 struct snd_pcm_hw_params *params, unsigned int best_rate) 788 struct snd_pcm_hw_params *params, unsigned int best_rate)
801{ 789{
802 struct snd_interval *it; 790 const struct snd_interval *it;
803 struct snd_pcm_hw_params *save; 791 struct snd_pcm_hw_params *save;
804 unsigned int rate, prev; 792 unsigned int rate, prev;
805 793
@@ -807,7 +795,7 @@ static int choose_rate(struct snd_pcm_substream *substream,
807 if (save == NULL) 795 if (save == NULL)
808 return -ENOMEM; 796 return -ENOMEM;
809 *save = *params; 797 *save = *params;
810 it = hw_param_interval(save, SNDRV_PCM_HW_PARAM_RATE); 798 it = hw_param_interval_c(save, SNDRV_PCM_HW_PARAM_RATE);
811 799
812 /* try multiples of the best rate */ 800 /* try multiples of the best rate */
813 rate = best_rate; 801 rate = best_rate;
@@ -848,7 +836,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
848 int direct; 836 int direct;
849 snd_pcm_format_t format, sformat; 837 snd_pcm_format_t format, sformat;
850 int n; 838 int n;
851 struct snd_mask sformat_mask; 839 const struct snd_mask *sformat_mask;
852 struct snd_mask mask; 840 struct snd_mask mask;
853 841
854 if (trylock) { 842 if (trylock) {
@@ -891,18 +879,18 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
891 879
892 format = snd_pcm_oss_format_from(runtime->oss.format); 880 format = snd_pcm_oss_format_from(runtime->oss.format);
893 881
894 sformat_mask = *hw_param_mask(sparams, SNDRV_PCM_HW_PARAM_FORMAT); 882 sformat_mask = hw_param_mask_c(sparams, SNDRV_PCM_HW_PARAM_FORMAT);
895 if (direct) 883 if (direct)
896 sformat = format; 884 sformat = format;
897 else 885 else
898 sformat = snd_pcm_plug_slave_format(format, &sformat_mask); 886 sformat = snd_pcm_plug_slave_format(format, sformat_mask);
899 887
900 if ((__force int)sformat < 0 || 888 if ((__force int)sformat < 0 ||
901 !snd_mask_test(&sformat_mask, (__force int)sformat)) { 889 !snd_mask_test(sformat_mask, (__force int)sformat)) {
902 for (sformat = (__force snd_pcm_format_t)0; 890 for (sformat = (__force snd_pcm_format_t)0;
903 (__force int)sformat <= (__force int)SNDRV_PCM_FORMAT_LAST; 891 (__force int)sformat <= (__force int)SNDRV_PCM_FORMAT_LAST;
904 sformat = (__force snd_pcm_format_t)((__force int)sformat + 1)) { 892 sformat = (__force snd_pcm_format_t)((__force int)sformat + 1)) {
905 if (snd_mask_test(&sformat_mask, (__force int)sformat) && 893 if (snd_mask_test(sformat_mask, (__force int)sformat) &&
906 snd_pcm_oss_format_to(sformat) >= 0) 894 snd_pcm_oss_format_to(sformat) >= 0)
907 break; 895 break;
908 } 896 }
@@ -1191,14 +1179,8 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const
1191 if (ret < 0) 1179 if (ret < 0)
1192 break; 1180 break;
1193 } 1181 }
1194 if (in_kernel) { 1182 ret = __snd_pcm_lib_xfer(substream, (void *)ptr, true,
1195 mm_segment_t fs; 1183 frames, in_kernel);
1196 fs = snd_enter_user();
1197 ret = snd_pcm_lib_write(substream, (void __force __user *)ptr, frames);
1198 snd_leave_user(fs);
1199 } else {
1200 ret = snd_pcm_lib_write(substream, (void __force __user *)ptr, frames);
1201 }
1202 if (ret != -EPIPE && ret != -ESTRPIPE) 1184 if (ret != -EPIPE && ret != -ESTRPIPE)
1203 break; 1185 break;
1204 /* test, if we can't store new data, because the stream */ 1186 /* test, if we can't store new data, because the stream */
@@ -1234,14 +1216,8 @@ snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *p
1234 ret = snd_pcm_oss_capture_position_fixup(substream, &delay); 1216 ret = snd_pcm_oss_capture_position_fixup(substream, &delay);
1235 if (ret < 0) 1217 if (ret < 0)
1236 break; 1218 break;
1237 if (in_kernel) { 1219 ret = __snd_pcm_lib_xfer(substream, (void *)ptr, true,
1238 mm_segment_t fs; 1220 frames, in_kernel);
1239 fs = snd_enter_user();
1240 ret = snd_pcm_lib_read(substream, (void __force __user *)ptr, frames);
1241 snd_leave_user(fs);
1242 } else {
1243 ret = snd_pcm_lib_read(substream, (void __force __user *)ptr, frames);
1244 }
1245 if (ret == -EPIPE) { 1221 if (ret == -EPIPE) {
1246 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { 1222 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
1247 ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); 1223 ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
@@ -1256,7 +1232,8 @@ snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *p
1256 return ret; 1232 return ret;
1257} 1233}
1258 1234
1259snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel) 1235#ifdef CONFIG_SND_PCM_OSS_PLUGINS
1236snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames)
1260{ 1237{
1261 struct snd_pcm_runtime *runtime = substream->runtime; 1238 struct snd_pcm_runtime *runtime = substream->runtime;
1262 int ret; 1239 int ret;
@@ -1273,14 +1250,7 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void
1273 if (ret < 0) 1250 if (ret < 0)
1274 break; 1251 break;
1275 } 1252 }
1276 if (in_kernel) { 1253 ret = snd_pcm_kernel_writev(substream, bufs, frames);
1277 mm_segment_t fs;
1278 fs = snd_enter_user();
1279 ret = snd_pcm_lib_writev(substream, (void __user **)bufs, frames);
1280 snd_leave_user(fs);
1281 } else {
1282 ret = snd_pcm_lib_writev(substream, (void __user **)bufs, frames);
1283 }
1284 if (ret != -EPIPE && ret != -ESTRPIPE) 1254 if (ret != -EPIPE && ret != -ESTRPIPE)
1285 break; 1255 break;
1286 1256
@@ -1292,7 +1262,7 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void
1292 return ret; 1262 return ret;
1293} 1263}
1294 1264
1295snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel) 1265snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames)
1296{ 1266{
1297 struct snd_pcm_runtime *runtime = substream->runtime; 1267 struct snd_pcm_runtime *runtime = substream->runtime;
1298 int ret; 1268 int ret;
@@ -1313,19 +1283,13 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void *
1313 if (ret < 0) 1283 if (ret < 0)
1314 break; 1284 break;
1315 } 1285 }
1316 if (in_kernel) { 1286 ret = snd_pcm_kernel_readv(substream, bufs, frames);
1317 mm_segment_t fs;
1318 fs = snd_enter_user();
1319 ret = snd_pcm_lib_readv(substream, (void __user **)bufs, frames);
1320 snd_leave_user(fs);
1321 } else {
1322 ret = snd_pcm_lib_readv(substream, (void __user **)bufs, frames);
1323 }
1324 if (ret != -EPIPE && ret != -ESTRPIPE) 1287 if (ret != -EPIPE && ret != -ESTRPIPE)
1325 break; 1288 break;
1326 } 1289 }
1327 return ret; 1290 return ret;
1328} 1291}
1292#endif /* CONFIG_SND_PCM_OSS_PLUGINS */
1329 1293
1330static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const char *buf, size_t bytes, int in_kernel) 1294static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const char *buf, size_t bytes, int in_kernel)
1331{ 1295{
@@ -1650,27 +1614,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1650 size = runtime->control->appl_ptr % runtime->period_size; 1614 size = runtime->control->appl_ptr % runtime->period_size;
1651 if (size > 0) { 1615 if (size > 0) {
1652 size = runtime->period_size - size; 1616 size = runtime->period_size - size;
1653 if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) { 1617 if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED)
1654 size = (runtime->frame_bits * size) / 8; 1618 snd_pcm_lib_write(substream, NULL, size);
1655 while (size > 0) { 1619 else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
1656 mm_segment_t fs; 1620 snd_pcm_lib_writev(substream, NULL, size);
1657 size_t size1 = size < runtime->oss.period_bytes ? size : runtime->oss.period_bytes;
1658 size -= size1;
1659 size1 *= 8;
1660 size1 /= runtime->sample_bits;
1661 snd_pcm_format_set_silence(runtime->format,
1662 runtime->oss.buffer,
1663 size1);
1664 size1 /= runtime->channels; /* frames */
1665 fs = snd_enter_user();
1666 snd_pcm_lib_write(substream, (void __force __user *)runtime->oss.buffer, size1);
1667 snd_leave_user(fs);
1668 }
1669 } else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
1670 void __user *buffers[runtime->channels];
1671 memset(buffers, 0, runtime->channels * sizeof(void *));
1672 snd_pcm_lib_writev(substream, buffers, size);
1673 }
1674 } 1621 }
1675 mutex_unlock(&runtime->oss.params_lock); 1622 mutex_unlock(&runtime->oss.params_lock);
1676 /* 1623 /*
@@ -1780,7 +1727,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
1780 int direct; 1727 int direct;
1781 struct snd_pcm_hw_params *params; 1728 struct snd_pcm_hw_params *params;
1782 unsigned int formats = 0; 1729 unsigned int formats = 0;
1783 struct snd_mask format_mask; 1730 const struct snd_mask *format_mask;
1784 int fmt; 1731 int fmt;
1785 1732
1786 if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0) 1733 if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
@@ -1802,12 +1749,12 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
1802 return -ENOMEM; 1749 return -ENOMEM;
1803 _snd_pcm_hw_params_any(params); 1750 _snd_pcm_hw_params_any(params);
1804 err = snd_pcm_hw_refine(substream, params); 1751 err = snd_pcm_hw_refine(substream, params);
1805 format_mask = *hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 1752 format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
1806 kfree(params); 1753 kfree(params);
1807 if (err < 0) 1754 if (err < 0)
1808 return err; 1755 return err;
1809 for (fmt = 0; fmt < 32; ++fmt) { 1756 for (fmt = 0; fmt < 32; ++fmt) {
1810 if (snd_mask_test(&format_mask, fmt)) { 1757 if (snd_mask_test(format_mask, fmt)) {
1811 int f = snd_pcm_oss_format_to(fmt); 1758 int f = snd_pcm_oss_format_to(fmt);
1812 if (f >= 0) 1759 if (f >= 0)
1813 formats |= f; 1760 formats |= f;