OSDN Git Service

ALSA: emu8000: Convert to generic PCM copy ops
authorTakashi Iwai <tiwai@suse.de>
Tue, 15 Aug 2023 19:01:17 +0000 (21:01 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 18 Aug 2023 10:18:19 +0000 (12:18 +0200)
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>
sound/isa/sb/emu8000_pcm.c

index c8afc43..c05935c 100644 (file)
@@ -409,39 +409,25 @@ do { \
                return -EAGAIN;\
 } while (0)
 
-enum {
-       COPY_USER, COPY_KERNEL, FILL_SILENCE,
-};
-
-#define GET_VAL(sval, buf, mode)                                       \
+#define GET_VAL(sval, iter)                                            \
        do {                                                            \
-               switch (mode) {                                         \
-               case FILL_SILENCE:                                      \
+               if (!iter)                                              \
                        sval = 0;                                       \
-                       break;                                          \
-               case COPY_KERNEL:                                       \
-                       sval = *buf++;                                  \
-                       break;                                          \
-               default:                                                \
-                       if (get_user(sval, (unsigned short __user *)buf)) \
-                               return -EFAULT;                         \
-                       buf++;                                          \
-                       break;                                          \
-               }                                                       \
+               else if (copy_from_iter(&sval, 2, iter) != 2)           \
+                       return -EFAULT;                                 \
        } while (0)
 
 #ifdef USE_NONINTERLEAVE
 
-#define LOOP_WRITE(rec, offset, _buf, count, mode)             \
+#define LOOP_WRITE(rec, offset, iter, count)                   \
        do {                                                    \
                struct snd_emu8000 *emu = (rec)->emu;           \
-               unsigned short *buf = (__force unsigned short *)(_buf); \
                snd_emu8000_write_wait(emu, 1);                 \
                EMU8000_SMALW_WRITE(emu, offset);               \
                while (count > 0) {                             \
                        unsigned short sval;                    \
                        CHECK_SCHEDULER();                      \
-                       GET_VAL(sval, buf, mode);               \
+                       GET_VAL(sval, iter);                    \
                        EMU8000_SMLD_WRITE(emu, sval);          \
                        count--;                                \
                }                                               \
@@ -450,27 +436,14 @@ enum {
 /* copy one channel block */
 static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
                          int voice, unsigned long pos,
-                         void __user *src, unsigned long count)
+                         struct iov_iter *src, unsigned long count)
 {
        struct snd_emu8k_pcm *rec = subs->runtime->private_data;
 
        /* convert to word unit */
        pos = (pos << 1) + rec->loop_start[voice];
        count <<= 1;
-       LOOP_WRITE(rec, pos, src, count, COPY_USER);
-       return 0;
-}
-
-static int emu8k_pcm_copy_kernel(struct snd_pcm_substream *subs,
-                                int voice, unsigned long pos,
-                                void *src, unsigned long count)
-{
-       struct snd_emu8k_pcm *rec = subs->runtime->private_data;
-
-       /* convert to word unit */
-       pos = (pos << 1) + rec->loop_start[voice];
-       count <<= 1;
-       LOOP_WRITE(rec, pos, src, count, COPY_KERNEL);
+       LOOP_WRITE(rec, pos, src, count);
        return 0;
 }
 
@@ -483,16 +456,15 @@ static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
        /* convert to word unit */
        pos = (pos << 1) + rec->loop_start[voice];
        count <<= 1;
-       LOOP_WRITE(rec, pos, NULL, count, FILL_SILENCE);
+       LOOP_WRITE(rec, pos, USER_SOCKPTR(NULL), count);
        return 0;
 }
 
 #else /* interleave */
 
-#define LOOP_WRITE(rec, pos, _buf, count, mode)                                \
+#define LOOP_WRITE(rec, pos, iter, count)                              \
        do {                                                            \
                struct snd_emu8000 *emu = rec->emu;                     \
-               unsigned short *buf = (__force unsigned short *)(_buf); \
                snd_emu8000_write_wait(emu, 1);                         \
                EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]);     \
                if (rec->voices > 1)                                    \
@@ -500,11 +472,11 @@ static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
                while (count > 0) {                                     \
                        unsigned short sval;                            \
                        CHECK_SCHEDULER();                              \
-                       GET_VAL(sval, buf, mode);                       \
+                       GET_VAL(sval, iter);                            \
                        EMU8000_SMLD_WRITE(emu, sval);                  \
                        if (rec->voices > 1) {                          \
                                CHECK_SCHEDULER();                      \
-                               GET_VAL(sval, buf, mode);               \
+                               GET_VAL(sval, iter);                    \
                                EMU8000_SMRD_WRITE(emu, sval);          \
                        }                                               \
                        count--;                                        \
@@ -518,27 +490,14 @@ static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
  */
 static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
                          int voice, unsigned long pos,
-                         void __user *src, unsigned long count)
-{
-       struct snd_emu8k_pcm *rec = subs->runtime->private_data;
-
-       /* convert to frames */
-       pos = bytes_to_frames(subs->runtime, pos);
-       count = bytes_to_frames(subs->runtime, count);
-       LOOP_WRITE(rec, pos, src, count, COPY_USER);
-       return 0;
-}
-
-static int emu8k_pcm_copy_kernel(struct snd_pcm_substream *subs,
-                                int voice, unsigned long pos,
-                                void *src, unsigned long count)
+                         struct iov_iter *src, unsigned long count)
 {
        struct snd_emu8k_pcm *rec = subs->runtime->private_data;
 
        /* convert to frames */
        pos = bytes_to_frames(subs->runtime, pos);
        count = bytes_to_frames(subs->runtime, count);
-       LOOP_WRITE(rec, pos, src, count, COPY_KERNEL);
+       LOOP_WRITE(rec, pos, src, count);
        return 0;
 }
 
@@ -550,7 +509,7 @@ static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
        /* convert to frames */
        pos = bytes_to_frames(subs->runtime, pos);
        count = bytes_to_frames(subs->runtime, count);
-       LOOP_WRITE(rec, pos, NULL, count, FILL_SILENCE);
+       LOOP_WRITE(rec, pos, NULL, count);
        return 0;
 }
 #endif
@@ -666,8 +625,7 @@ static const struct snd_pcm_ops emu8k_pcm_ops = {
        .prepare =      emu8k_pcm_prepare,
        .trigger =      emu8k_pcm_trigger,
        .pointer =      emu8k_pcm_pointer,
-       .copy_user =    emu8k_pcm_copy,
-       .copy_kernel =  emu8k_pcm_copy_kernel,
+       .copy =         emu8k_pcm_copy,
        .fill_silence = emu8k_pcm_silence,
 };