diff options
Diffstat (limited to 'sound/oss/emu10k1/cardwi.c')
-rw-r--r-- | sound/oss/emu10k1/cardwi.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/sound/oss/emu10k1/cardwi.c b/sound/oss/emu10k1/cardwi.c index 8bbf44b881b4..060d1be94d33 100644 --- a/sound/oss/emu10k1/cardwi.c +++ b/sound/oss/emu10k1/cardwi.c | |||
@@ -304,11 +304,12 @@ void emu10k1_wavein_getxfersize(struct wiinst *wiinst, u32 * size) | |||
304 | } | 304 | } |
305 | } | 305 | } |
306 | 306 | ||
307 | static void copy_block(u8 __user *dst, u8 * src, u32 str, u32 len, u8 cov) | 307 | static int copy_block(u8 __user *dst, u8 * src, u32 str, u32 len, u8 cov) |
308 | { | 308 | { |
309 | if (cov == 1) | 309 | if (cov == 1) { |
310 | __copy_to_user(dst, src + str, len); | 310 | if (__copy_to_user(dst, src + str, len)) |
311 | else { | 311 | return -EFAULT; |
312 | } else { | ||
312 | u8 byte; | 313 | u8 byte; |
313 | u32 i; | 314 | u32 i; |
314 | 315 | ||
@@ -316,22 +317,26 @@ static void copy_block(u8 __user *dst, u8 * src, u32 str, u32 len, u8 cov) | |||
316 | 317 | ||
317 | for (i = 0; i < len; i++) { | 318 | for (i = 0; i < len; i++) { |
318 | byte = src[2 * i] ^ 0x80; | 319 | byte = src[2 * i] ^ 0x80; |
319 | __copy_to_user(dst + i, &byte, 1); | 320 | if (__copy_to_user(dst + i, &byte, 1)) |
321 | return -EFAULT; | ||
320 | } | 322 | } |
321 | } | 323 | } |
324 | |||
325 | return 0; | ||
322 | } | 326 | } |
323 | 327 | ||
324 | void emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 __user *data, u32 * size) | 328 | int emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 __user *data, u32 * size) |
325 | { | 329 | { |
326 | struct wavein_buffer *buffer = &wiinst->buffer; | 330 | struct wavein_buffer *buffer = &wiinst->buffer; |
327 | u32 sizetocopy, sizetocopy_now, start; | 331 | u32 sizetocopy, sizetocopy_now, start; |
328 | unsigned long flags; | 332 | unsigned long flags; |
333 | int ret; | ||
329 | 334 | ||
330 | sizetocopy = min_t(u32, buffer->size, *size); | 335 | sizetocopy = min_t(u32, buffer->size, *size); |
331 | *size = sizetocopy; | 336 | *size = sizetocopy; |
332 | 337 | ||
333 | if (!sizetocopy) | 338 | if (!sizetocopy) |
334 | return; | 339 | return 0; |
335 | 340 | ||
336 | spin_lock_irqsave(&wiinst->lock, flags); | 341 | spin_lock_irqsave(&wiinst->lock, flags); |
337 | start = buffer->pos; | 342 | start = buffer->pos; |
@@ -345,11 +350,17 @@ void emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 __user *data, u32 * size) | |||
345 | if (sizetocopy > sizetocopy_now) { | 350 | if (sizetocopy > sizetocopy_now) { |
346 | sizetocopy -= sizetocopy_now; | 351 | sizetocopy -= sizetocopy_now; |
347 | 352 | ||
348 | copy_block(data, buffer->addr, start, sizetocopy_now, buffer->cov); | 353 | ret = copy_block(data, buffer->addr, start, sizetocopy_now, |
349 | copy_block(data + sizetocopy_now, buffer->addr, 0, sizetocopy, buffer->cov); | 354 | buffer->cov); |
355 | if (ret == 0) | ||
356 | ret = copy_block(data + sizetocopy_now, buffer->addr, 0, | ||
357 | sizetocopy, buffer->cov); | ||
350 | } else { | 358 | } else { |
351 | copy_block(data, buffer->addr, start, sizetocopy, buffer->cov); | 359 | ret = copy_block(data, buffer->addr, start, sizetocopy, |
360 | buffer->cov); | ||
352 | } | 361 | } |
362 | |||
363 | return ret; | ||
353 | } | 364 | } |
354 | 365 | ||
355 | void emu10k1_wavein_update(struct emu10k1_card *card, struct wiinst *wiinst) | 366 | void emu10k1_wavein_update(struct emu10k1_card *card, struct wiinst *wiinst) |