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

Commit 549b5a98 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: core: Add compat ioctl support for listen driver"

parents 15c844c7 72402ba8
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -480,6 +480,20 @@ static int snd_compressed_ioctl32(struct snd_pcm_substream *substream,
	pr_debug("%s called with cmd = %d\n", __func__, cmd);
	return err;
}
static int snd_user_ioctl32(struct snd_pcm_substream *substream,
			  unsigned int cmd, void __user *arg)
{
	struct snd_pcm_runtime *runtime;
	int err = -ENOIOCTLCMD;

	if (PCM_RUNTIME_CHECK(substream))
		return -ENXIO;
	runtime = substream->runtime;
	if (substream->ops->compat_ioctl)
		err = substream->ops->compat_ioctl(substream, cmd, arg);
	return err;
}


static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
{
@@ -551,6 +565,8 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
	default:
		if (_IOC_TYPE(cmd) == 'C')
			return snd_compressed_ioctl32(substream, cmd, argp);
		else if (_IOC_TYPE(cmd) == 'U')
			return snd_user_ioctl32(substream, cmd, argp);
	}

	return -ENOIOCTLCMD;
+162 −2
Original line number Diff line number Diff line
@@ -311,6 +311,165 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,

	return rc;
}
#ifdef CONFIG_COMPAT
struct snd_lsm_sound_model32 {
	compat_uptr_t data;
	u32 data_size;
	enum lsm_detection_mode detection_mode;
	u16 min_keyw_confidence;
	u16 min_user_confidence;
	bool detect_failure;
};

struct snd_lsm_event_status32 {
	u16 status;
	u16 payload_size;
	u8 payload[0];
};

struct snd_lsm_sound_model_v2_32 {
	compat_uptr_t data;
	compat_uptr_t confidence_level;
	u32 data_size;
	enum lsm_detection_mode detection_mode;
	u8 num_confidence_levels;
	bool detect_failure;
};

enum {
	SNDRV_LSM_REG_SND_MODEL32 =
	_IOW('U', 0x00, struct snd_lsm_sound_model32),
	SNDRV_LSM_EVENT_STATUS32 =
	_IOW('U', 0x02, struct snd_lsm_event_status32),
	SNDRV_LSM_REG_SND_MODEL_V2_32 = _IOW('U', 0x07,
	struct snd_lsm_sound_model_v2_32),
};

static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream,
			  unsigned int cmd, void __user *arg)
{
	struct snd_pcm_runtime *runtime;
	int err = 0;
	u32 size = 0;

	if (PCM_RUNTIME_CHECK(substream))
		return -ENXIO;
	runtime = substream->runtime;
	switch (cmd) {
	case SNDRV_LSM_REG_SND_MODEL32: {
		struct snd_lsm_sound_model32 snd_model32;
		struct snd_lsm_sound_model snd_model;
		if (copy_from_user(&snd_model32, arg,
			sizeof(struct snd_lsm_sound_model32))) {
			err = -EFAULT;
			pr_err("%s: copy user failed ioctl %s, size %zd\n",
				__func__, "SNDRV_LSM_REG_SND_MODEL32",
				sizeof(struct snd_lsm_sound_model32));
		} else {
			snd_model.data = compat_ptr(snd_model32.data);
			snd_model.data_size = snd_model32.data_size;
			snd_model.detect_failure = snd_model32.detect_failure;
			snd_model.detection_mode = snd_model32.detection_mode;
			snd_model.min_keyw_confidence =
			snd_model32.min_keyw_confidence;
			snd_model.min_user_confidence =
			snd_model32.min_user_confidence;
			cmd = SNDRV_LSM_REG_SND_MODEL;
			err = msm_lsm_ioctl_shared(substream, cmd, &snd_model);
			if (err)
				pr_err("%s ioctl %s failed err %d\n",
				__func__, "SNDRV_LSM_REG_SND_MODEL32", err);
		}
		break;
	}
	case SNDRV_LSM_EVENT_STATUS32: {
		struct snd_lsm_event_status32 userarg32, *user32 = NULL;
		struct snd_lsm_event_status *user = NULL;
		if (copy_from_user(&userarg32, arg, sizeof(userarg32))) {
			pr_err("%s: err copyuser ioctl %s\n",
			__func__, "SNDRV_LSM_EVENT_STATUS32");
			return -EFAULT;
		}
		size = sizeof(*user) + userarg32.payload_size;
		user = kmalloc(size, GFP_KERNEL);
		if (!user) {
			pr_err("%s: Allocation failed event status size %d\n",
			__func__, size);
			err = -EFAULT;
		} else {
			cmd = SNDRV_LSM_EVENT_STATUS;
			user->payload_size = userarg32.payload_size;
			err = msm_lsm_ioctl_shared(substream, cmd, user);
		}
		/* Update size with actual payload size */
		size = sizeof(userarg32) + user->payload_size;
		if (!err && !access_ok(VERIFY_WRITE, arg, size)) {
			pr_err("%s: write verify failed size %d\n",
			__func__, size);
			err = -EFAULT;
		}
		if (!err) {
			user32 = kmalloc(size, GFP_KERNEL);
			if (!user32) {
				pr_err("%s: Allocation event user status size %d\n"
				, __func__, size);
				err = -EFAULT;
			} else {
				user32->status = user->status;
				user32->payload_size = user->payload_size;
				memcpy(user32->payload,
				user->payload, user32->payload_size);
			}
		}
		if (!err && (copy_to_user(arg, user32, size))) {
			pr_err("%s: failed to copy payload %d",
			__func__, size);
			err = -EFAULT;
		}
		kfree(user);
		kfree(user32);
		if (err)
			pr_err("%s: lsmevent failed %d", __func__, err);
		break;
	}
	case SNDRV_LSM_REG_SND_MODEL_V2_32: {
		struct snd_lsm_sound_model_v2_32 snd_modelv232;
		struct snd_lsm_sound_model_v2 snd_modelv2;
		if (copy_from_user(&snd_modelv232, arg,
			sizeof(snd_modelv232))) {
			err = -EFAULT;
			pr_err("%s: copy user failed, size %zd %s\n", __func__,
			sizeof(struct snd_lsm_sound_model_v2_32),
			"SNDRV_LSM_REG_SND_MODEL_V2_32");
		} else {
			snd_modelv2.confidence_level =
			compat_ptr(snd_modelv232.confidence_level);
			snd_modelv2.data = compat_ptr(snd_modelv232.data);
			snd_modelv2.data_size = snd_modelv232.data_size;
			snd_modelv2.detect_failure =
			snd_modelv232.detect_failure;
			snd_modelv2.detection_mode =
			snd_modelv232.detection_mode;
			snd_modelv2.num_confidence_levels =
			snd_modelv232.num_confidence_levels;
			cmd = SNDRV_LSM_REG_SND_MODEL_V2;
			err = msm_lsm_ioctl_shared(substream, cmd,
				&snd_modelv2);
			if (err)
				pr_err("%s: ioctl %s failed\n", __func__,
				"SNDDRV_LSM_REG_SND_MODEL_V2_32");
		}
		break;
	}
	default:
		err = msm_lsm_ioctl_shared(substream, cmd, arg);
		break;
	}
	return err;
}
#else
#define msm_lsm_ioctl_compat NULL
#endif

static int msm_lsm_ioctl(struct snd_pcm_substream *substream,
			 unsigned int cmd, void *arg)
@@ -438,6 +597,8 @@ static int msm_lsm_open(struct snd_pcm_substream *substream)
		       __func__);
		return -ENOMEM;
	}
	spin_lock_init(&prtd->event_lock);
	init_waitqueue_head(&prtd->event_wait);
	prtd->substream = substream;
	prtd->lsm_client = q6lsm_client_alloc(
				(lsm_app_cb)lsm_event_handler, prtd);
@@ -470,8 +631,6 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream)
	pr_debug("%s: Session ID %d\n", __func__,
		 prtd->lsm_client->session);
	prtd->lsm_client->started = false;
	spin_lock_init(&prtd->event_lock);
	init_waitqueue_head(&prtd->event_wait);
	runtime->private_data = prtd;
	return 0;
}
@@ -501,6 +660,7 @@ static struct snd_pcm_ops msm_lsm_ops = {
	.close          = msm_lsm_close,
	.ioctl          = msm_lsm_ioctl,
	.prepare	= msm_lsm_prepare,
	.compat_ioctl   = msm_lsm_ioctl_compat,
};

static int msm_asoc_lsm_new(struct snd_soc_pcm_runtime *rtd)