diff options
Diffstat (limited to 'sound/core/pcm_lib.c')
-rw-r--r-- | sound/core/pcm_lib.c | 150 |
1 files changed, 85 insertions, 65 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 1533f0379e9..921691080f3 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; |
@@ -903,12 +908,12 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, | |||
903 | EXPORT_SYMBOL(snd_pcm_hw_rule_add); | 908 | EXPORT_SYMBOL(snd_pcm_hw_rule_add); |
904 | 909 | ||
905 | /** | 910 | /** |
906 | * snd_pcm_hw_constraint_mask | 911 | * snd_pcm_hw_constraint_mask - apply the given bitmap mask constraint |
907 | * @runtime: PCM runtime instance | 912 | * @runtime: PCM runtime instance |
908 | * @var: hw_params variable to apply the mask | 913 | * @var: hw_params variable to apply the mask |
909 | * @mask: the bitmap mask | 914 | * @mask: the bitmap mask |
910 | * | 915 | * |
911 | * Apply the constraint of the given bitmap mask to a mask parameter. | 916 | * Apply the constraint of the given bitmap mask to a 32-bit mask parameter. |
912 | */ | 917 | */ |
913 | int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, | 918 | int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, |
914 | u_int32_t mask) | 919 | u_int32_t mask) |
@@ -923,12 +928,12 @@ int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param | |||
923 | } | 928 | } |
924 | 929 | ||
925 | /** | 930 | /** |
926 | * snd_pcm_hw_constraint_mask64 | 931 | * snd_pcm_hw_constraint_mask64 - apply the given bitmap mask constraint |
927 | * @runtime: PCM runtime instance | 932 | * @runtime: PCM runtime instance |
928 | * @var: hw_params variable to apply the mask | 933 | * @var: hw_params variable to apply the mask |
929 | * @mask: the 64bit bitmap mask | 934 | * @mask: the 64bit bitmap mask |
930 | * | 935 | * |
931 | * Apply the constraint of the given bitmap mask to a mask parameter. | 936 | * Apply the constraint of the given bitmap mask to a 64-bit mask parameter. |
932 | */ | 937 | */ |
933 | int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, | 938 | int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, |
934 | u_int64_t mask) | 939 | u_int64_t mask) |
@@ -944,7 +949,7 @@ int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_par | |||
944 | } | 949 | } |
945 | 950 | ||
946 | /** | 951 | /** |
947 | * snd_pcm_hw_constraint_integer | 952 | * snd_pcm_hw_constraint_integer - apply an integer constraint to an interval |
948 | * @runtime: PCM runtime instance | 953 | * @runtime: PCM runtime instance |
949 | * @var: hw_params variable to apply the integer constraint | 954 | * @var: hw_params variable to apply the integer constraint |
950 | * | 955 | * |
@@ -959,7 +964,7 @@ int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_pa | |||
959 | EXPORT_SYMBOL(snd_pcm_hw_constraint_integer); | 964 | EXPORT_SYMBOL(snd_pcm_hw_constraint_integer); |
960 | 965 | ||
961 | /** | 966 | /** |
962 | * snd_pcm_hw_constraint_minmax | 967 | * snd_pcm_hw_constraint_minmax - apply a min/max range constraint to an interval |
963 | * @runtime: PCM runtime instance | 968 | * @runtime: PCM runtime instance |
964 | * @var: hw_params variable to apply the range | 969 | * @var: hw_params variable to apply the range |
965 | * @min: the minimal value | 970 | * @min: the minimal value |
@@ -990,7 +995,7 @@ static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, | |||
990 | 995 | ||
991 | 996 | ||
992 | /** | 997 | /** |
993 | * snd_pcm_hw_constraint_list | 998 | * snd_pcm_hw_constraint_list - apply a list of constraints to a parameter |
994 | * @runtime: PCM runtime instance | 999 | * @runtime: PCM runtime instance |
995 | * @cond: condition bits | 1000 | * @cond: condition bits |
996 | * @var: hw_params variable to apply the list constraint | 1001 | * @var: hw_params variable to apply the list constraint |
@@ -1026,7 +1031,7 @@ static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, | |||
1026 | } | 1031 | } |
1027 | 1032 | ||
1028 | /** | 1033 | /** |
1029 | * snd_pcm_hw_constraint_ratnums | 1034 | * snd_pcm_hw_constraint_ratnums - apply ratnums constraint to a parameter |
1030 | * @runtime: PCM runtime instance | 1035 | * @runtime: PCM runtime instance |
1031 | * @cond: condition bits | 1036 | * @cond: condition bits |
1032 | * @var: hw_params variable to apply the ratnums constraint | 1037 | * @var: hw_params variable to apply the ratnums constraint |
@@ -1059,7 +1064,7 @@ static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params, | |||
1059 | } | 1064 | } |
1060 | 1065 | ||
1061 | /** | 1066 | /** |
1062 | * snd_pcm_hw_constraint_ratdens | 1067 | * snd_pcm_hw_constraint_ratdens - apply ratdens constraint to a parameter |
1063 | * @runtime: PCM runtime instance | 1068 | * @runtime: PCM runtime instance |
1064 | * @cond: condition bits | 1069 | * @cond: condition bits |
1065 | * @var: hw_params variable to apply the ratdens constraint | 1070 | * @var: hw_params variable to apply the ratdens constraint |
@@ -1090,7 +1095,7 @@ static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, | |||
1090 | } | 1095 | } |
1091 | 1096 | ||
1092 | /** | 1097 | /** |
1093 | * snd_pcm_hw_constraint_msbits | 1098 | * snd_pcm_hw_constraint_msbits - add a hw constraint msbits rule |
1094 | * @runtime: PCM runtime instance | 1099 | * @runtime: PCM runtime instance |
1095 | * @cond: condition bits | 1100 | * @cond: condition bits |
1096 | * @width: sample bits width | 1101 | * @width: sample bits width |
@@ -1118,7 +1123,7 @@ static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params, | |||
1118 | } | 1123 | } |
1119 | 1124 | ||
1120 | /** | 1125 | /** |
1121 | * snd_pcm_hw_constraint_step | 1126 | * snd_pcm_hw_constraint_step - add a hw constraint step rule |
1122 | * @runtime: PCM runtime instance | 1127 | * @runtime: PCM runtime instance |
1123 | * @cond: condition bits | 1128 | * @cond: condition bits |
1124 | * @var: hw_params variable to apply the step constraint | 1129 | * @var: hw_params variable to apply the step constraint |
@@ -1149,7 +1154,7 @@ static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm | |||
1149 | } | 1154 | } |
1150 | 1155 | ||
1151 | /** | 1156 | /** |
1152 | * snd_pcm_hw_constraint_pow2 | 1157 | * snd_pcm_hw_constraint_pow2 - add a hw constraint power-of-2 rule |
1153 | * @runtime: PCM runtime instance | 1158 | * @runtime: PCM runtime instance |
1154 | * @cond: condition bits | 1159 | * @cond: condition bits |
1155 | * @var: hw_params variable to apply the power-of-2 constraint | 1160 | * @var: hw_params variable to apply the power-of-2 constraint |
@@ -1197,13 +1202,13 @@ void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params) | |||
1197 | EXPORT_SYMBOL(_snd_pcm_hw_params_any); | 1202 | EXPORT_SYMBOL(_snd_pcm_hw_params_any); |
1198 | 1203 | ||
1199 | /** | 1204 | /** |
1200 | * snd_pcm_hw_param_value | 1205 | * snd_pcm_hw_param_value - return @params field @var value |
1201 | * @params: the hw_params instance | 1206 | * @params: the hw_params instance |
1202 | * @var: parameter to retrieve | 1207 | * @var: parameter to retrieve |
1203 | * @dir: pointer to the direction (-1,0,1) or NULL | 1208 | * @dir: pointer to the direction (-1,0,1) or %NULL |
1204 | * | 1209 | * |
1205 | * Return the value for field PAR if it's fixed in configuration space | 1210 | * Return the value for field @var if it's fixed in configuration space |
1206 | * defined by PARAMS. Return -EINVAL otherwise | 1211 | * defined by @params. Return -%EINVAL otherwise. |
1207 | */ | 1212 | */ |
1208 | int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, | 1213 | int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, |
1209 | snd_pcm_hw_param_t var, int *dir) | 1214 | snd_pcm_hw_param_t var, int *dir) |
@@ -1266,13 +1271,13 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, | |||
1266 | 1271 | ||
1267 | 1272 | ||
1268 | /** | 1273 | /** |
1269 | * snd_pcm_hw_param_first | 1274 | * snd_pcm_hw_param_first - refine config space and return minimum value |
1270 | * @pcm: PCM instance | 1275 | * @pcm: PCM instance |
1271 | * @params: the hw_params instance | 1276 | * @params: the hw_params instance |
1272 | * @var: parameter to retrieve | 1277 | * @var: parameter to retrieve |
1273 | * @dir: pointer to the direction (-1,0,1) or NULL | 1278 | * @dir: pointer to the direction (-1,0,1) or %NULL |
1274 | * | 1279 | * |
1275 | * Inside configuration space defined by PARAMS remove from PAR all | 1280 | * Inside configuration space defined by @params remove from @var all |
1276 | * values > minimum. Reduce configuration space accordingly. | 1281 | * values > minimum. Reduce configuration space accordingly. |
1277 | * Return the minimum. | 1282 | * Return the minimum. |
1278 | */ | 1283 | */ |
@@ -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 | } |
@@ -1311,13 +1317,13 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, | |||
1311 | 1317 | ||
1312 | 1318 | ||
1313 | /** | 1319 | /** |
1314 | * snd_pcm_hw_param_last | 1320 | * snd_pcm_hw_param_last - refine config space and return maximum value |
1315 | * @pcm: PCM instance | 1321 | * @pcm: PCM instance |
1316 | * @params: the hw_params instance | 1322 | * @params: the hw_params instance |
1317 | * @var: parameter to retrieve | 1323 | * @var: parameter to retrieve |
1318 | * @dir: pointer to the direction (-1,0,1) or NULL | 1324 | * @dir: pointer to the direction (-1,0,1) or %NULL |
1319 | * | 1325 | * |
1320 | * Inside configuration space defined by PARAMS remove from PAR all | 1326 | * Inside configuration space defined by @params remove from @var all |
1321 | * values < maximum. Reduce configuration space accordingly. | 1327 | * values < maximum. Reduce configuration space accordingly. |
1322 | * Return the maximum. | 1328 | * Return the maximum. |
1323 | */ | 1329 | */ |
@@ -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 | } |
@@ -1338,11 +1345,11 @@ int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, | |||
1338 | EXPORT_SYMBOL(snd_pcm_hw_param_last); | 1345 | EXPORT_SYMBOL(snd_pcm_hw_param_last); |
1339 | 1346 | ||
1340 | /** | 1347 | /** |
1341 | * snd_pcm_hw_param_choose | 1348 | * snd_pcm_hw_param_choose - choose a configuration defined by @params |
1342 | * @pcm: PCM instance | 1349 | * @pcm: PCM instance |
1343 | * @params: the hw_params instance | 1350 | * @params: the hw_params instance |
1344 | * | 1351 | * |
1345 | * Choose one configuration from configuration space defined by PARAMS | 1352 | * Choose one configuration from configuration space defined by @params. |
1346 | * The configuration chosen is that obtained fixing in this order: | 1353 | * The configuration chosen is that obtained fixing in this order: |
1347 | * first access, first format, first subformat, min channels, | 1354 | * first access, first format, first subformat, min channels, |
1348 | * min rate, min period time, max buffer size, min tick time | 1355 | * min rate, min period time, max buffer size, min tick time |
@@ -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 | ||