Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: emu8000: Convert to generic PCM copy ops

This patch converts the SB Emu8000 driver code to use the new unified
PCM copy callback. The conversion is a bit complicated because of
many open code in emu8000_pcm.c. GET_VAL() and LOOP_WRITE() macros
were rewritten / simplified with copy_from_iter(). As
copy_from_iter() updates the internal offset value, we can drop the
corresponding part, too.

Link: https://lore.kernel.org/r/20230815190136.8987-7-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+16 -58
+16 -58
sound/isa/sb/emu8000_pcm.c
··· 409 409 return -EAGAIN;\ 410 410 } while (0) 411 411 412 - enum { 413 - COPY_USER, COPY_KERNEL, FILL_SILENCE, 414 - }; 415 - 416 - #define GET_VAL(sval, buf, mode) \ 412 + #define GET_VAL(sval, iter) \ 417 413 do { \ 418 - switch (mode) { \ 419 - case FILL_SILENCE: \ 414 + if (!iter) \ 420 415 sval = 0; \ 421 - break; \ 422 - case COPY_KERNEL: \ 423 - sval = *buf++; \ 424 - break; \ 425 - default: \ 426 - if (get_user(sval, (unsigned short __user *)buf)) \ 427 - return -EFAULT; \ 428 - buf++; \ 429 - break; \ 430 - } \ 416 + else if (copy_from_iter(&sval, 2, iter) != 2) \ 417 + return -EFAULT; \ 431 418 } while (0) 432 419 433 420 #ifdef USE_NONINTERLEAVE 434 421 435 - #define LOOP_WRITE(rec, offset, _buf, count, mode) \ 422 + #define LOOP_WRITE(rec, offset, iter, count) \ 436 423 do { \ 437 424 struct snd_emu8000 *emu = (rec)->emu; \ 438 - unsigned short *buf = (__force unsigned short *)(_buf); \ 439 425 snd_emu8000_write_wait(emu, 1); \ 440 426 EMU8000_SMALW_WRITE(emu, offset); \ 441 427 while (count > 0) { \ 442 428 unsigned short sval; \ 443 429 CHECK_SCHEDULER(); \ 444 - GET_VAL(sval, buf, mode); \ 430 + GET_VAL(sval, iter); \ 445 431 EMU8000_SMLD_WRITE(emu, sval); \ 446 432 count--; \ 447 433 } \ ··· 436 450 /* copy one channel block */ 437 451 static int emu8k_pcm_copy(struct snd_pcm_substream *subs, 438 452 int voice, unsigned long pos, 439 - void __user *src, unsigned long count) 453 + struct iov_iter *src, unsigned long count) 440 454 { 441 455 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 442 456 443 457 /* convert to word unit */ 444 458 pos = (pos << 1) + rec->loop_start[voice]; 445 459 count <<= 1; 446 - LOOP_WRITE(rec, pos, src, count, COPY_USER); 447 - return 0; 448 - } 449 - 450 - static int emu8k_pcm_copy_kernel(struct snd_pcm_substream *subs, 451 - int voice, unsigned long pos, 452 - void *src, unsigned long count) 453 - { 454 - struct snd_emu8k_pcm *rec = subs->runtime->private_data; 455 - 456 - /* convert to word unit */ 457 - pos = (pos << 1) + rec->loop_start[voice]; 458 - count <<= 1; 459 - LOOP_WRITE(rec, pos, src, count, COPY_KERNEL); 460 + LOOP_WRITE(rec, pos, src, count); 460 461 return 0; 461 462 } 462 463 ··· 456 483 /* convert to word unit */ 457 484 pos = (pos << 1) + rec->loop_start[voice]; 458 485 count <<= 1; 459 - LOOP_WRITE(rec, pos, NULL, count, FILL_SILENCE); 486 + LOOP_WRITE(rec, pos, USER_SOCKPTR(NULL), count); 460 487 return 0; 461 488 } 462 489 463 490 #else /* interleave */ 464 491 465 - #define LOOP_WRITE(rec, pos, _buf, count, mode) \ 492 + #define LOOP_WRITE(rec, pos, iter, count) \ 466 493 do { \ 467 494 struct snd_emu8000 *emu = rec->emu; \ 468 - unsigned short *buf = (__force unsigned short *)(_buf); \ 469 495 snd_emu8000_write_wait(emu, 1); \ 470 496 EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]); \ 471 497 if (rec->voices > 1) \ ··· 472 500 while (count > 0) { \ 473 501 unsigned short sval; \ 474 502 CHECK_SCHEDULER(); \ 475 - GET_VAL(sval, buf, mode); \ 503 + GET_VAL(sval, iter); \ 476 504 EMU8000_SMLD_WRITE(emu, sval); \ 477 505 if (rec->voices > 1) { \ 478 506 CHECK_SCHEDULER(); \ 479 - GET_VAL(sval, buf, mode); \ 507 + GET_VAL(sval, iter); \ 480 508 EMU8000_SMRD_WRITE(emu, sval); \ 481 509 } \ 482 510 count--; \ ··· 490 518 */ 491 519 static int emu8k_pcm_copy(struct snd_pcm_substream *subs, 492 520 int voice, unsigned long pos, 493 - void __user *src, unsigned long count) 521 + struct iov_iter *src, unsigned long count) 494 522 { 495 523 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 496 524 497 525 /* convert to frames */ 498 526 pos = bytes_to_frames(subs->runtime, pos); 499 527 count = bytes_to_frames(subs->runtime, count); 500 - LOOP_WRITE(rec, pos, src, count, COPY_USER); 501 - return 0; 502 - } 503 - 504 - static int emu8k_pcm_copy_kernel(struct snd_pcm_substream *subs, 505 - int voice, unsigned long pos, 506 - void *src, unsigned long count) 507 - { 508 - struct snd_emu8k_pcm *rec = subs->runtime->private_data; 509 - 510 - /* convert to frames */ 511 - pos = bytes_to_frames(subs->runtime, pos); 512 - count = bytes_to_frames(subs->runtime, count); 513 - LOOP_WRITE(rec, pos, src, count, COPY_KERNEL); 528 + LOOP_WRITE(rec, pos, src, count); 514 529 return 0; 515 530 } 516 531 ··· 509 550 /* convert to frames */ 510 551 pos = bytes_to_frames(subs->runtime, pos); 511 552 count = bytes_to_frames(subs->runtime, count); 512 - LOOP_WRITE(rec, pos, NULL, count, FILL_SILENCE); 553 + LOOP_WRITE(rec, pos, NULL, count); 513 554 return 0; 514 555 } 515 556 #endif ··· 625 666 .prepare = emu8k_pcm_prepare, 626 667 .trigger = emu8k_pcm_trigger, 627 668 .pointer = emu8k_pcm_pointer, 628 - .copy_user = emu8k_pcm_copy, 629 - .copy_kernel = emu8k_pcm_copy_kernel, 669 + .copy = emu8k_pcm_copy, 630 670 .fill_silence = emu8k_pcm_silence, 631 671 }; 632 672