clear-pkgs-linux-iot-lts2018/0886-ASoC-Skl-Virt-Handle-t...

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