Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5442a73a authored by Pierre-Louis Bossart's avatar Pierre-Louis Bossart Committed by Takashi Iwai
Browse files

ALSA: core: pass audio tstamp config from userspace in compat mode



Let userspace select audio timestamp config, ignore and zero all
other fields
Use audio_tstamp_data to retrieve config and pass report back to
user space

Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 38ca2a4d
Loading
Loading
Loading
Loading
+23 −5
Original line number Diff line number Diff line
@@ -194,18 +194,30 @@ struct snd_pcm_status32 {
	u32 avail_max;
	u32 overrange;
	s32 suspended_state;
	u32 reserved_alignment;
	u32 audio_tstamp_data;
	struct compat_timespec audio_tstamp;
	unsigned char reserved[56-sizeof(struct compat_timespec)];
	struct compat_timespec driver_tstamp;
	u32 audio_tstamp_accuracy;
	unsigned char reserved[52-2*sizeof(struct compat_timespec)];
} __attribute__((packed));


static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,
				      struct snd_pcm_status32 __user *src)
				      struct snd_pcm_status32 __user *src,
				      bool ext)
{
	struct snd_pcm_status status;
	int err;

	memset(&status, 0, sizeof(status));
	/*
	 * with extension, parameters are read/write,
	 * get audio_tstamp_data from user,
	 * ignore rest of status structure
	 */
	if (ext && get_user(status.audio_tstamp_data,
				(u32 __user *)(&src->audio_tstamp_data)))
		return -EFAULT;
	err = snd_pcm_status(substream, &status);
	if (err < 0)
		return err;
@@ -222,7 +234,10 @@ static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,
	    put_user(status.avail_max, &src->avail_max) ||
	    put_user(status.overrange, &src->overrange) ||
	    put_user(status.suspended_state, &src->suspended_state) ||
	    compat_put_timespec(&status.audio_tstamp, &src->audio_tstamp))
	    put_user(status.audio_tstamp_data, &src->audio_tstamp_data) ||
	    compat_put_timespec(&status.audio_tstamp, &src->audio_tstamp) ||
	    compat_put_timespec(&status.driver_tstamp, &src->driver_tstamp) ||
	    put_user(status.audio_tstamp_accuracy, &src->audio_tstamp_accuracy))
		return -EFAULT;

	return err;
@@ -457,6 +472,7 @@ enum {
	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_STATUS_EXT32 = _IOWR('A', 0x24, struct snd_pcm_status32),
	SNDRV_PCM_IOCTL_DELAY32 = _IOR('A', 0x21, s32),
	SNDRV_PCM_IOCTL_CHANNEL_INFO32 = _IOR('A', 0x32, struct snd_pcm_channel_info32),
	SNDRV_PCM_IOCTL_REWIND32 = _IOW('A', 0x46, u32),
@@ -517,7 +533,9 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
	case SNDRV_PCM_IOCTL_SW_PARAMS32:
		return snd_pcm_ioctl_sw_params_compat(substream, argp);
	case SNDRV_PCM_IOCTL_STATUS32:
		return snd_pcm_status_user_compat(substream, argp);
		return snd_pcm_status_user_compat(substream, argp, false);
	case SNDRV_PCM_IOCTL_STATUS_EXT32:
		return snd_pcm_status_user_compat(substream, argp, true);
	case SNDRV_PCM_IOCTL_SYNC_PTR32:
		return snd_pcm_ioctl_sync_ptr_compat(substream, argp);
	case SNDRV_PCM_IOCTL_CHANNEL_INFO32: