qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH 22/27] virtio-snd: Add VIRTIO_SND_R_PCM_RELEASE handler


From: Shreyansh Chouhan
Subject: [RFC PATCH 22/27] virtio-snd: Add VIRTIO_SND_R_PCM_RELEASE handler
Date: Thu, 29 Apr 2021 17:34:40 +0530

Signed-off-by: Shreyansh Chouhan <chouhan.shreyansh2702@gmail.com>
---
 hw/audio/virtio-snd.c | 66 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
index 8be3fb9bf5..56e07a41f8 100644
--- a/hw/audio/virtio-snd.c
+++ b/hw/audio/virtio-snd.c
@@ -789,6 +789,69 @@ static uint32_t virtio_snd_handle_pcm_stop(VirtIOSound *s,
     return sz;
 }
 
+/*
+ * Releases the resources allocated to a stream. Sepearated from the handler
+ * so that the code could be reused in the unrealize function.
+ *
+ * TODO: Doesn't handle the stream buffers that are yet to be played.
+ *
+ * @s: VirtIOSound card
+ * @stream: stream id
+ */
+static uint32_t virtio_snd_pcm_release_impl(VirtIOSound *s, uint32_t stream)
+{
+    virtio_snd_pcm_stream *st = virtio_snd_pcm_get_stream(s, stream);
+    if (st) {
+        virtio_snd_err("already released %d\n", stream);
+        return VIRTIO_SND_S_BAD_MSG;
+    }
+
+    if (st->voice.out) {
+        AUD_close_out(&s->card, st->voice.out);
+    } else if (st->voice.in) {
+        AUD_close_in(&s->card, st->voice.in);
+    }
+
+    if (st->elems) {
+        int nelems = virtio_snd_pcm_get_nelems(st);
+        for (int i = 0; i < nelems; i++) {
+            g_free(st->elems[i]);
+            st->elems[i] = NULL;
+        }
+        g_free(st->elems);
+        st->elems = NULL;
+    }
+
+    g_free(s->streams[stream]);
+    s->streams[stream] = NULL;
+    return VIRTIO_SND_S_OK;
+}
+
+/*
+ * Handles VIRTIO_SND_R_PCM_RELEASE.
+ * The function writes the response to the virtqueue element.
+ * Returns the used size in bytes.
+ * TODO: Doesn't handle the stream buffers that are yet to be played.
+ *
+ * @s: VirtIOSound card
+ * @elem: The request element from control queue
+ */
+static uint32_t virtio_snd_handle_pcm_release(VirtIOSound *s,
+                                              VirtQueueElement *elem)
+{
+    virtio_snd_pcm_hdr req;
+    virtio_snd_hdr resp;
+    size_t sz;
+    sz = iov_from_buf(elem->out_sg, elem->out_num, 0, &req, sizeof(req));
+    assert(sz == sizeof(virtio_snd_pcm_hdr));
+
+    virtio_snd_pcm_release_impl(s, req.stream_id);
+
+    sz = iov_from_buf(elem->in_sg, elem->in_num, 0, &resp, sizeof(resp));
+    assert(sz == sizeof(virtio_snd_hdr));
+    return sz;
+}
+
 /* The control queue handler. Pops an element from the control virtqueue,
  * checks the header and performs the requested action. Finally marks the
  * element as used.
@@ -849,7 +912,8 @@ static void virtio_snd_handle_ctrl(VirtIODevice *vdev, 
VirtQueue *vq)
             sz = virtio_snd_handle_pcm_stop(s, elem);
             goto done;
         } else if (ctrl.code == VIRTIO_SND_R_PCM_RELEASE) {
-            virtio_snd_log("VIRTIO_SND_R_PCM_RELEASE");
+            sz = virtio_snd_handle_pcm_release(s, elem);
+            goto done;
         } else {
             /* error */
             virtio_snd_err("virtio snd header not recognized: %d\n", 
ctrl.code);
-- 
2.25.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]