diff options
Diffstat (limited to 'sound/core/oss/pcm_oss.c')
-rw-r--r-- | sound/core/oss/pcm_oss.c | 101 |
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); | |||
67 | static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file); | 67 | static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file); |
68 | static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file); | 68 | static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file); |
69 | 69 | ||
70 | static 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 | |||
77 | static 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, | |||
799 | static int choose_rate(struct snd_pcm_substream *substream, | 787 | static 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 | ||
1259 | snd_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 |
1236 | snd_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 | ||
1295 | snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel) | 1265 | snd_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 | ||
1330 | static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const char *buf, size_t bytes, int in_kernel) | 1294 | static 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; |