125 lines
3.8 KiB
Diff
125 lines
3.8 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Pawel Furtak <pawel.furtak@intel.com>
|
|
Date: Wed, 16 Jan 2019 08:18:00 +0100
|
|
Subject: [PATCH] ASoC: Skl: Virt: Handle timed out message replies
|
|
|
|
Ignoring timed out messages may result in inconsistent
|
|
state of UOS and SOS (e.g. stream is open on SOS,
|
|
but closed on GOS). This patch adds mechanism to recover
|
|
after message time out (e.g. close stream after timed out
|
|
open message)
|
|
|
|
Change-Id: I716f793d3668ceabe3d10557c21b973806a29710
|
|
Tracked-On: OAM-74848
|
|
Signed-off-by: Pawel Furtak <pawel.furtak@intel.com>
|
|
Reviewed-by: Janca, Grzegorz <grzegorz.janca@intel.com>
|
|
Reviewed-by: Rojewski, Cezary <cezary.rojewski@intel.com>
|
|
Tested-by: Rojewski, Cezary <cezary.rojewski@intel.com>
|
|
---
|
|
.../soc/intel/skylake/virtio/skl-virtio-fe.c | 61 ++++++++++++++++++-
|
|
.../soc/intel/skylake/virtio/skl-virtio-fe.h | 3 +
|
|
2 files changed, 63 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/sound/soc/intel/skylake/virtio/skl-virtio-fe.c b/sound/soc/intel/skylake/virtio/skl-virtio-fe.c
|
|
index 66a57d5..2985c87 100644
|
|
--- a/sound/soc/intel/skylake/virtio/skl-virtio-fe.c
|
|
+++ b/sound/soc/intel/skylake/virtio/skl-virtio-fe.c
|
|
@@ -96,6 +96,22 @@ struct vfe_kcontrol *vfe_find_kcontrol(struct snd_skl_vfe *vfe,
|
|
return NULL;
|
|
}
|
|
|
|
+const struct snd_pcm *vfe_skl_find_pcm_by_name(struct skl *skl, char *pcm_name)
|
|
+{
|
|
+ const struct snd_soc_pcm_runtime *rtd;
|
|
+ int ret = vfe_is_valid_pcm_id(pcm_name);
|
|
+
|
|
+ if (ret < 0)
|
|
+ return NULL;
|
|
+
|
|
+ list_for_each_entry(rtd, &skl->component->card->rtd_list, list) {
|
|
+ if (strncmp(rtd->pcm->id, pcm_name,
|
|
+ ARRAY_SIZE(rtd->pcm->id)) == 0)
|
|
+ return rtd->pcm;
|
|
+ }
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
static int vfe_send_virtio_msg(struct snd_skl_vfe *vfe,
|
|
struct virtqueue *vq, struct scatterlist *sgs, int sg_count,
|
|
void *data, bool out)
|
|
@@ -318,8 +334,10 @@ static void vfe_not_tx_done(struct virtqueue *vq)
|
|
break;
|
|
|
|
msg_status = atomic_read(&msg->status);
|
|
- if (msg_status != VFE_MSG_PENDING)
|
|
+ if (msg_status == VFE_MSG_TIMED_OUT) {
|
|
+ vfe_handle_timedout_not_tx_msg(vfe, msg);
|
|
goto free_msg;
|
|
+ }
|
|
|
|
if (msg->rx_buf) {
|
|
memcpy(msg->rx_data, msg->rx_buf, msg->rx_size);
|
|
@@ -593,6 +611,47 @@ snd_pcm_uframes_t vfe_pcm_pointer(struct snd_pcm_substream *substream)
|
|
return substr_info ? substr_info->hw_ptr : 0;
|
|
}
|
|
|
|
+static void vfe_handle_timedout_pcm_msg(struct snd_skl_vfe *vfe,
|
|
+ struct vfe_ipc_msg *msg)
|
|
+{
|
|
+ struct snd_pcm_substream *substream;
|
|
+ const struct vfe_pcm_info *pcm_desc = &msg->header.desc.pcm;
|
|
+ const struct snd_pcm *pcm =
|
|
+ vfe_skl_find_pcm_by_name(&vfe->sdev, pcm_desc->pcm_id);
|
|
+ int direction = pcm_desc->direction;
|
|
+
|
|
+ if (!pcm)
|
|
+ return;
|
|
+
|
|
+ substream = pcm->streams[direction].substream;
|
|
+
|
|
+ switch (msg->header.cmd) {
|
|
+ case VFE_MSG_PCM_OPEN:
|
|
+ vfe_pcm_close(substream);
|
|
+ break;
|
|
+ default:
|
|
+ dev_info(&vfe->vdev->dev,
|
|
+ "Timed out PCM message %d not handled",
|
|
+ msg->header.cmd);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+void vfe_handle_timedout_not_tx_msg(struct snd_skl_vfe *vfe,
|
|
+ struct vfe_ipc_msg *msg)
|
|
+{
|
|
+ switch (msg->header.cmd & VFE_MSG_TYPE_MASK) {
|
|
+ case VFE_MSG_PCM:
|
|
+ vfe_handle_timedout_pcm_msg(vfe, msg);
|
|
+ break;
|
|
+ default:
|
|
+ dev_info(&vfe->vdev->dev,
|
|
+ "Timed out message %d not handled",
|
|
+ msg->header.cmd);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
static const char *const vfe_skl_vq_names[SKL_VIRTIO_NUM_OF_VQS] = {
|
|
SKL_VIRTIO_IPC_CMD_TX_VQ_NAME,
|
|
SKL_VIRTIO_IPC_CMD_RX_VQ_NAME,
|
|
diff --git a/sound/soc/intel/skylake/virtio/skl-virtio-fe.h b/sound/soc/intel/skylake/virtio/skl-virtio-fe.h
|
|
index 5656d0b..1fec990 100644
|
|
--- a/sound/soc/intel/skylake/virtio/skl-virtio-fe.h
|
|
+++ b/sound/soc/intel/skylake/virtio/skl-virtio-fe.h
|
|
@@ -61,4 +61,7 @@ struct snd_skl_vfe {
|
|
struct platform_device *pdev, struct snd_soc_card *card);
|
|
};
|
|
|
|
+void vfe_handle_timedout_not_tx_msg(struct snd_skl_vfe *vfe,
|
|
+ struct vfe_ipc_msg *msg);
|
|
+
|
|
#endif
|
|
--
|
|
2.21.0
|
|
|