aboutsummaryrefslogtreecommitdiff
path: root/sound/core/pcm_compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/pcm_compat.c')
-rw-r--r--sound/core/pcm_compat.c154
1 files changed, 79 insertions, 75 deletions
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 4b6307df846..af49721ba0e 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -21,8 +21,9 @@
/* This file included from pcm_native.c */
#include <linux/compat.h>
+#include <linux/slab.h>
-static int snd_pcm_ioctl_delay_compat(snd_pcm_substream_t *substream,
+static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream,
s32 __user *src)
{
snd_pcm_sframes_t delay;
@@ -39,7 +40,7 @@ static int snd_pcm_ioctl_delay_compat(snd_pcm_substream_t *substream,
return err;
}
-static int snd_pcm_ioctl_rewind_compat(snd_pcm_substream_t *substream,
+static int snd_pcm_ioctl_rewind_compat(struct snd_pcm_substream *substream,
u32 __user *src)
{
snd_pcm_uframes_t frames;
@@ -56,7 +57,7 @@ static int snd_pcm_ioctl_rewind_compat(snd_pcm_substream_t *substream,
return err < 0 ? err : 0;
}
-static int snd_pcm_ioctl_forward_compat(snd_pcm_substream_t *substream,
+static int snd_pcm_ioctl_forward_compat(struct snd_pcm_substream *substream,
u32 __user *src)
{
snd_pcm_uframes_t frames;
@@ -73,12 +74,12 @@ static int snd_pcm_ioctl_forward_compat(snd_pcm_substream_t *substream,
return err < 0 ? err : 0;
}
-struct sndrv_pcm_hw_params32 {
+struct snd_pcm_hw_params32 {
u32 flags;
- struct sndrv_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; /* this must be identical */
- struct sndrv_mask mres[5]; /* reserved masks */
- struct sndrv_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
- struct sndrv_interval ires[9]; /* reserved intervals */
+ struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; /* this must be identical */
+ struct snd_mask mres[5]; /* reserved masks */
+ struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
+ struct snd_interval ires[9]; /* reserved intervals */
u32 rmask;
u32 cmask;
u32 info;
@@ -89,7 +90,7 @@ struct sndrv_pcm_hw_params32 {
unsigned char reserved[64];
};
-struct sndrv_pcm_sw_params32 {
+struct snd_pcm_sw_params32 {
s32 tstamp_mode;
u32 period_step;
u32 sleep_min;
@@ -104,7 +105,7 @@ struct sndrv_pcm_sw_params32 {
};
/* recalcuate the boundary within 32bit */
-static snd_pcm_uframes_t recalculate_boundary(snd_pcm_runtime_t *runtime)
+static snd_pcm_uframes_t recalculate_boundary(struct snd_pcm_runtime *runtime)
{
snd_pcm_uframes_t boundary;
@@ -116,10 +117,10 @@ static snd_pcm_uframes_t recalculate_boundary(snd_pcm_runtime_t *runtime)
return boundary;
}
-static int snd_pcm_ioctl_sw_params_compat(snd_pcm_substream_t *substream,
- struct sndrv_pcm_sw_params32 __user *src)
+static int snd_pcm_ioctl_sw_params_compat(struct snd_pcm_substream *substream,
+ struct snd_pcm_sw_params32 __user *src)
{
- snd_pcm_sw_params_t params;
+ struct snd_pcm_sw_params params;
snd_pcm_uframes_t boundary;
int err;
@@ -149,17 +150,17 @@ static int snd_pcm_ioctl_sw_params_compat(snd_pcm_substream_t *substream,
return err;
}
-struct sndrv_pcm_channel_info32 {
+struct snd_pcm_channel_info32 {
u32 channel;
u32 offset;
u32 first;
u32 step;
};
-static int snd_pcm_ioctl_channel_info_compat(snd_pcm_substream_t *substream,
- struct sndrv_pcm_channel_info32 __user *src)
+static int snd_pcm_ioctl_channel_info_compat(struct snd_pcm_substream *substream,
+ struct snd_pcm_channel_info32 __user *src)
{
- snd_pcm_channel_info_t info;
+ struct snd_pcm_channel_info info;
int err;
if (get_user(info.channel, &src->channel) ||
@@ -178,7 +179,7 @@ static int snd_pcm_ioctl_channel_info_compat(snd_pcm_substream_t *substream,
return err;
}
-struct sndrv_pcm_status32 {
+struct snd_pcm_status32 {
s32 state;
struct compat_timespec trigger_tstamp;
struct compat_timespec tstamp;
@@ -189,14 +190,16 @@ struct sndrv_pcm_status32 {
u32 avail_max;
u32 overrange;
s32 suspended_state;
- unsigned char reserved[60];
+ u32 reserved_alignment;
+ struct compat_timespec audio_tstamp;
+ unsigned char reserved[56-sizeof(struct compat_timespec)];
} __attribute__((packed));
-static int snd_pcm_status_user_compat(snd_pcm_substream_t *substream,
- struct sndrv_pcm_status32 __user *src)
+static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,
+ struct snd_pcm_status32 __user *src)
{
- snd_pcm_status_t status;
+ struct snd_pcm_status status;
int err;
err = snd_pcm_status(substream, &status);
@@ -204,42 +207,38 @@ static int snd_pcm_status_user_compat(snd_pcm_substream_t *substream,
return err;
if (put_user(status.state, &src->state) ||
- put_user(status.trigger_tstamp.tv_sec, &src->trigger_tstamp.tv_sec) ||
- put_user(status.trigger_tstamp.tv_nsec, &src->trigger_tstamp.tv_nsec) ||
- put_user(status.tstamp.tv_sec, &src->tstamp.tv_sec) ||
- put_user(status.tstamp.tv_nsec, &src->tstamp.tv_nsec) ||
+ compat_put_timespec(&status.trigger_tstamp, &src->trigger_tstamp) ||
+ compat_put_timespec(&status.tstamp, &src->tstamp) ||
put_user(status.appl_ptr, &src->appl_ptr) ||
put_user(status.hw_ptr, &src->hw_ptr) ||
put_user(status.delay, &src->delay) ||
put_user(status.avail, &src->avail) ||
put_user(status.avail_max, &src->avail_max) ||
put_user(status.overrange, &src->overrange) ||
- put_user(status.suspended_state, &src->suspended_state))
+ put_user(status.suspended_state, &src->suspended_state) ||
+ compat_put_timespec(&status.audio_tstamp, &src->audio_tstamp))
return -EFAULT;
return err;
}
/* both for HW_PARAMS and HW_REFINE */
-static int snd_pcm_ioctl_hw_params_compat(snd_pcm_substream_t *substream,
+static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
int refine,
- struct sndrv_pcm_hw_params32 __user *data32)
+ struct snd_pcm_hw_params32 __user *data32)
{
- struct sndrv_pcm_hw_params *data;
- snd_pcm_runtime_t *runtime;
+ struct snd_pcm_hw_params *data;
+ struct snd_pcm_runtime *runtime;
int err;
if (! (runtime = substream->runtime))
return -ENOTTY;
- data = kmalloc(sizeof(*data), GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
/* only fifo_size is different, so just copy all */
- if (copy_from_user(data, data32, sizeof(*data32))) {
- err = -EFAULT;
- goto error;
- }
+ data = memdup_user(data32, sizeof(*data32));
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
if (refine)
err = snd_pcm_hw_refine(substream, data);
else
@@ -265,14 +264,14 @@ static int snd_pcm_ioctl_hw_params_compat(snd_pcm_substream_t *substream,
/*
*/
-struct sndrv_xferi32 {
+struct snd_xferi32 {
s32 result;
u32 buf;
u32 frames;
};
-static int snd_pcm_ioctl_xferi_compat(snd_pcm_substream_t *substream,
- int dir, struct sndrv_xferi32 __user *data32)
+static int snd_pcm_ioctl_xferi_compat(struct snd_pcm_substream *substream,
+ int dir, struct snd_xferi32 __user *data32)
{
compat_caddr_t buf;
u32 frames;
@@ -303,7 +302,7 @@ static int snd_pcm_ioctl_xferi_compat(snd_pcm_substream_t *substream,
/* snd_xfern needs remapping of bufs */
-struct sndrv_xfern32 {
+struct snd_xfern32 {
s32 result;
u32 bufs; /* this is void **; */
u32 frames;
@@ -315,8 +314,8 @@ struct sndrv_xfern32 {
* handler there expands again the same 128 pointers on stack, so it is better
* to handle the function (calling pcm_readv/writev) directly in this handler.
*/
-static int snd_pcm_ioctl_xfern_compat(snd_pcm_substream_t *substream,
- int dir, struct sndrv_xfern32 __user *data32)
+static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
+ int dir, struct snd_xfern32 __user *data32)
{
compat_caddr_t buf;
compat_caddr_t __user *bufptr;
@@ -344,7 +343,7 @@ static int snd_pcm_ioctl_xfern_compat(snd_pcm_substream_t *substream,
kfree(bufs);
return -EFAULT;
}
- bufs[ch] = compat_ptr(ptr);
+ bufs[i] = compat_ptr(ptr);
bufptr++;
}
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
@@ -360,44 +359,46 @@ static int snd_pcm_ioctl_xfern_compat(snd_pcm_substream_t *substream,
}
-struct sndrv_pcm_mmap_status32 {
+struct snd_pcm_mmap_status32 {
s32 state;
s32 pad1;
u32 hw_ptr;
struct compat_timespec tstamp;
s32 suspended_state;
+ struct compat_timespec audio_tstamp;
} __attribute__((packed));
-struct sndrv_pcm_mmap_control32 {
+struct snd_pcm_mmap_control32 {
u32 appl_ptr;
u32 avail_min;
};
-struct sndrv_pcm_sync_ptr32 {
+struct snd_pcm_sync_ptr32 {
u32 flags;
union {
- struct sndrv_pcm_mmap_status32 status;
+ struct snd_pcm_mmap_status32 status;
unsigned char reserved[64];
} s;
union {
- struct sndrv_pcm_mmap_control32 control;
+ struct snd_pcm_mmap_control32 control;
unsigned char reserved[64];
} c;
} __attribute__((packed));
-static int snd_pcm_ioctl_sync_ptr_compat(snd_pcm_substream_t *substream,
- struct sndrv_pcm_sync_ptr32 __user *src)
+static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
+ struct snd_pcm_sync_ptr32 __user *src)
{
- snd_pcm_runtime_t *runtime = substream->runtime;
- volatile struct sndrv_pcm_mmap_status *status;
- volatile struct sndrv_pcm_mmap_control *control;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ volatile struct snd_pcm_mmap_status *status;
+ volatile struct snd_pcm_mmap_control *control;
u32 sflags;
- struct sndrv_pcm_mmap_control scontrol;
- struct sndrv_pcm_mmap_status sstatus;
+ struct snd_pcm_mmap_control scontrol;
+ struct snd_pcm_mmap_status sstatus;
snd_pcm_uframes_t boundary;
int err;
- snd_assert(runtime, return -EINVAL);
+ if (snd_BUG_ON(!runtime))
+ return -EINVAL;
if (get_user(sflags, &src->flags) ||
get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
@@ -427,12 +428,14 @@ static int snd_pcm_ioctl_sync_ptr_compat(snd_pcm_substream_t *substream,
sstatus.hw_ptr = status->hw_ptr % boundary;
sstatus.tstamp = status->tstamp;
sstatus.suspended_state = status->suspended_state;
+ sstatus.audio_tstamp = status->audio_tstamp;
snd_pcm_stream_unlock_irq(substream);
if (put_user(sstatus.state, &src->s.status.state) ||
put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
- put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp.tv_sec) ||
- put_user(sstatus.tstamp.tv_nsec, &src->s.status.tstamp.tv_nsec) ||
+ compat_put_timespec(&sstatus.tstamp, &src->s.status.tstamp) ||
put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
+ compat_put_timespec(&sstatus.audio_tstamp,
+ &src->s.status.audio_tstamp) ||
put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
put_user(scontrol.avail_min, &src->c.control.avail_min))
return -EFAULT;
@@ -444,26 +447,26 @@ static int snd_pcm_ioctl_sync_ptr_compat(snd_pcm_substream_t *substream,
/*
*/
enum {
- SNDRV_PCM_IOCTL_HW_REFINE32 = _IOWR('A', 0x10, struct sndrv_pcm_hw_params32),
- SNDRV_PCM_IOCTL_HW_PARAMS32 = _IOWR('A', 0x11, struct sndrv_pcm_hw_params32),
- SNDRV_PCM_IOCTL_SW_PARAMS32 = _IOWR('A', 0x13, struct sndrv_pcm_sw_params32),
- SNDRV_PCM_IOCTL_STATUS32 = _IOR('A', 0x20, struct sndrv_pcm_status32),
+ SNDRV_PCM_IOCTL_HW_REFINE32 = _IOWR('A', 0x10, struct snd_pcm_hw_params32),
+ SNDRV_PCM_IOCTL_HW_PARAMS32 = _IOWR('A', 0x11, struct snd_pcm_hw_params32),
+ SNDRV_PCM_IOCTL_SW_PARAMS32 = _IOWR('A', 0x13, struct snd_pcm_sw_params32),
+ SNDRV_PCM_IOCTL_STATUS32 = _IOR('A', 0x20, struct snd_pcm_status32),
SNDRV_PCM_IOCTL_DELAY32 = _IOR('A', 0x21, s32),
- SNDRV_PCM_IOCTL_CHANNEL_INFO32 = _IOR('A', 0x32, struct sndrv_pcm_channel_info32),
+ SNDRV_PCM_IOCTL_CHANNEL_INFO32 = _IOR('A', 0x32, struct snd_pcm_channel_info32),
SNDRV_PCM_IOCTL_REWIND32 = _IOW('A', 0x46, u32),
SNDRV_PCM_IOCTL_FORWARD32 = _IOW('A', 0x49, u32),
- SNDRV_PCM_IOCTL_WRITEI_FRAMES32 = _IOW('A', 0x50, struct sndrv_xferi32),
- SNDRV_PCM_IOCTL_READI_FRAMES32 = _IOR('A', 0x51, struct sndrv_xferi32),
- SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct sndrv_xfern32),
- SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct sndrv_xfern32),
- SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr32),
+ SNDRV_PCM_IOCTL_WRITEI_FRAMES32 = _IOW('A', 0x50, struct snd_xferi32),
+ SNDRV_PCM_IOCTL_READI_FRAMES32 = _IOR('A', 0x51, struct snd_xferi32),
+ SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct snd_xfern32),
+ SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32),
+ SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr32),
};
static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
{
- snd_pcm_file_t *pcm_file;
- snd_pcm_substream_t *substream;
+ struct snd_pcm_file *pcm_file;
+ struct snd_pcm_substream *substream;
void __user *argp = compat_ptr(arg);
pcm_file = file->private_data;
@@ -478,12 +481,13 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
* mmap of PCM status/control records because of the size
* incompatibility.
*/
- substream->no_mmap_ctrl = 1;
+ pcm_file->no_compat_mmap = 1;
switch (cmd) {
case SNDRV_PCM_IOCTL_PVERSION:
case SNDRV_PCM_IOCTL_INFO:
case SNDRV_PCM_IOCTL_TSTAMP:
+ case SNDRV_PCM_IOCTL_TTSTAMP:
case SNDRV_PCM_IOCTL_HWSYNC:
case SNDRV_PCM_IOCTL_PREPARE:
case SNDRV_PCM_IOCTL_RESET:
@@ -497,9 +501,9 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
case SNDRV_PCM_IOCTL_LINK:
case SNDRV_PCM_IOCTL_UNLINK:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return snd_pcm_playback_ioctl1(substream, cmd, argp);
+ return snd_pcm_playback_ioctl1(file, substream, cmd, argp);
else
- return snd_pcm_capture_ioctl1(substream, cmd, argp);
+ return snd_pcm_capture_ioctl1(file, substream, cmd, argp);
case SNDRV_PCM_IOCTL_HW_REFINE32:
return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
case SNDRV_PCM_IOCTL_HW_PARAMS32: