@@ -409,40 +409,28 @@ do { \
return -EAGAIN;\
} while (0)
-enum {
- COPY_USER, COPY_KERNEL, FILL_SILENCE,
-};
-
-#define GET_VAL(sval, buf, mode) \
+#define GET_VAL(sval, buf, offset) \
do { \
- switch (mode) { \
- case FILL_SILENCE: \
+ if (sockptr_is_null(buf)) \
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_sockptr_offset(&sval, buf, offset, 2)) \
+ return -EFAULT; \
} while (0)
#ifdef USE_NONINTERLEAVE
-#define LOOP_WRITE(rec, offset, _buf, count, mode) \
+#define LOOP_WRITE(rec, offset, buf, count) \
do { \
struct snd_emu8000 *emu = (rec)->emu; \
- unsigned short *buf = (__force unsigned short *)(_buf); \
+ unsigned int offset = 0; \
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, buf, offset); \
EMU8000_SMLD_WRITE(emu, sval); \
+ offset += 2; \
count--; \
} \
} while (0)
@@ -450,27 +438,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)
+ sockptr_t 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 +458,16 @@ 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, buf, count) \
do { \
struct snd_emu8000 *emu = rec->emu; \
- unsigned short *buf = (__force unsigned short *)(_buf); \
+ unsigned int offset = 0; \
snd_emu8000_write_wait(emu, 1); \
EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]); \
if (rec->voices > 1) \
@@ -500,12 +475,14 @@ 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, buf, offset); \
EMU8000_SMLD_WRITE(emu, sval); \
+ offset += 2; \
if (rec->voices > 1) { \
CHECK_SCHEDULER(); \
- GET_VAL(sval, buf, mode); \
+ GET_VAL(sval, buf, offset); \
EMU8000_SMRD_WRITE(emu, sval); \
+ offset += 2; \
} \
count--; \
} \
@@ -518,27 +495,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)
+ sockptr_t 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 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 +514,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, USER_SOCKPTR(NULL), count);
return 0;
}
#endif
@@ -666,8 +630,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,
};
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_sockptr_offset(). Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/isa/sb/emu8000_pcm.c | 79 ++++++++++---------------------------- 1 file changed, 21 insertions(+), 58 deletions(-)