This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 63e9e9cd33da3cc74d7a943a5dd8a030c244314f
Author: jinxiuxu <[email protected]>
AuthorDate: Thu May 22 13:05:11 2025 +0800

    drivers/virtio-snd: use two descriptors per period buffer
    
    Allocate the xfer header, the samples and the status together, laid
    out so that the device-readable part and the device-writable part are
    each contiguous.  A period then takes two descriptors instead of
    three, so more periods fit in the virtqueue.
    
    Signed-off-by: jinxiuxu <[email protected]>
---
 drivers/virtio/virtio-snd.c | 43 +++++++++++++++++++++++++------------------
 1 file changed, 25 insertions(+), 18 deletions(-)

diff --git a/drivers/virtio/virtio-snd.c b/drivers/virtio/virtio-snd.c
index da74fd29b70..2c9246d0d96 100644
--- a/drivers/virtio/virtio-snd.c
+++ b/drivers/virtio/virtio-snd.c
@@ -62,8 +62,8 @@ struct virtio_snd_format_map_s
 struct virtio_snd_buffer_s
 {
   struct ap_buffer_s apb;
-  struct virtio_snd_pcm_xfer xfer;
-  struct virtio_snd_pcm_status status;
+  struct virtio_snd_pcm_xfer *xfer;
+  struct virtio_snd_pcm_status *status;
   FAR struct audio_lowerhalf_s *dev;
 };
 
@@ -406,26 +406,26 @@ static int virtio_snd_send_pcm(FAR struct 
virtio_snd_dev_s *sdev,
   int idx = info->direction == VIRTIO_SND_D_INPUT ?
                                VIRTIO_SND_VQ_RX : VIRTIO_SND_VQ_TX;
   FAR struct virtqueue *vq = priv->vdev->vrings_info[idx].vq;
-  struct virtqueue_buf vb[3];
+  struct virtqueue_buf vb[2];
   irqstate_t flags;
 
-  vb[0].buf = &buf->xfer;
-  vb[0].len = sizeof(buf->xfer);
-  vb[1].buf = buf->apb.samp;
-  vb[1].len = sdev->period_bytes;
-  vb[2].buf = &buf->status;
-  vb[2].len = sizeof(buf->status);
-
-  flags = spin_lock_irqsave(&priv->lock);
   if (idx == VIRTIO_SND_VQ_RX)
     {
-      virtqueue_add_buffer(vq, vb, 1, 2, buf);
+      vb[0].buf = buf->xfer;
+      vb[0].len = sizeof(*(buf->xfer));
+      vb[1].buf = buf->apb.samp;
+      vb[1].len = sdev->period_bytes + sizeof(*(buf->status));
     }
   else
     {
-      virtqueue_add_buffer(vq, vb, 2, 1, buf);
+      vb[0].buf = buf->xfer;
+      vb[0].len = sizeof(*(buf->xfer)) + sdev->period_bytes;
+      vb[1].buf = buf->status;
+      vb[1].len = sizeof(*(buf->status));
     }
 
+  flags = spin_lock_irqsave(&priv->lock);
+  virtqueue_add_buffer(vq, vb, 1, 1, buf);
   virtqueue_kick(vq);
   sdev->cache_buffers++;
   if (sdev->cache_buffers > sdev->period_count)
@@ -779,7 +779,7 @@ static int virtio_snd_configure(FAR struct 
audio_lowerhalf_s *dev,
         ch = caps->ac_channels;
         sdev->frame_size = ch * bps / 8;
         sdev->period_count = MIN(CONFIG_DRIVERS_VIRTIO_SND_BUFFER_COUNT,
-                                 vq->vq_nentries / 3);
+                                 vq->vq_nentries / 2);
         sdev->period_bytes =
         virtio_snd_get_period_bytes(rate, ch, bps,
                                     CONFIG_DRIVERS_VIRTIO_SOUND_PERIOD_TIME *
@@ -952,7 +952,11 @@ static int virtio_snd_allocbuffer(FAR struct 
audio_lowerhalf_s *dev,
 
   DEBUGASSERT(desc->u.pbuffer != NULL);
 
-  buf = virtio_zalloc_buf(priv->vdev, sizeof(*buf) + desc->numbytes, 16);
+  buf = virtio_zalloc_buf(priv->vdev,
+                          sizeof(*buf) +
+                          sizeof(struct virtio_snd_pcm_xfer) +
+                          desc->numbytes +
+                          sizeof(struct virtio_snd_pcm_status), 16);
   if (buf == NULL)
     {
       vrterr("failed to allocate apb buffer\n");
@@ -963,12 +967,15 @@ static int virtio_snd_allocbuffer(FAR struct 
audio_lowerhalf_s *dev,
 
   buf->apb.crefs = 1;
   buf->apb.nmaxbytes = desc->numbytes;
-  buf->apb.samp = (FAR uint8_t *)(buf + 1);
+  buf->xfer = (FAR struct virtio_snd_pcm_xfer *)(buf + 1);
+  buf->apb.samp = (FAR uint8_t *)(buf->xfer + 1);
+  buf->status = (FAR struct virtio_snd_pcm_status *)
+                (buf->apb.samp + desc->numbytes);
 #ifdef CONFIG_AUDIO_MULTI_SESSION
   buf->apb.session = desc->session;
 #endif
-  buf->xfer.stream_id = sdev->index;
-  buf->status.status = VIRTIO_SND_S_IO_ERR;
+  buf->xfer->stream_id = sdev->index;
+  buf->status->status = VIRTIO_SND_S_IO_ERR;
   buf->dev = dev;
   nxmutex_init(&buf->apb.lock);
 

Reply via email to