diff mbox series

[v4,06/12] virtio-sound: handle VIRTIO_SND_R_PCM_INFO request

Message ID f267d41957025b3849324f459a8ed476aa89f828.1689857559.git.manos.pitsidianakis@linaro.org (mailing list archive)
State New, archived
Headers show
Series Add VIRTIO sound card | expand

Commit Message

Manos Pitsidianakis July 20, 2023, 12:57 p.m. UTC
Respond to the VIRTIO_SND_R_PCM_INFO control request with the parameters
of each requested PCM stream.

Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
---
 hw/virtio/trace-events |  1 +
 hw/virtio/virtio-snd.c | 78 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+)

Comments

Marc-André Lureau July 25, 2023, 2:29 p.m. UTC | #1
On Thu, Jul 20, 2023 at 4:59 PM Emmanouil Pitsidianakis <
manos.pitsidianakis@linaro.org> wrote:

> Respond to the VIRTIO_SND_R_PCM_INFO control request with the parameters
> of each requested PCM stream.
>
> Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
> ---
>  hw/virtio/trace-events |  1 +
>  hw/virtio/virtio-snd.c | 78 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 79 insertions(+)
>
> diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
> index 8a223e36e9..3e619f778b 100644
> --- a/hw/virtio/trace-events
> +++ b/hw/virtio/trace-events
> @@ -164,6 +164,7 @@ virtio_snd_vm_state_stopped(void) "vm state stopped"
>  virtio_snd_realize(void *snd) "snd %p: realize"
>  virtio_snd_unrealize(void *snd) "snd %p: unrealize"
>  virtio_snd_handle_ctrl(void *vdev, void *vq) "snd %p: handle ctrl event
> for queue %p"
> +virtio_snd_handle_pcm_info(uint32_t stream) "VIRTIO_SND_R_PCM_INFO called
> for stream %"PRIu32
>  virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code msg val
> = %"PRIu32" == %s"
>  virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called"
>  virtio_snd_handle_event(void) "event queue callback called"
> diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c
> index ca09c937c7..3f8b46f372 100644
> --- a/hw/virtio/virtio-snd.c
> +++ b/hw/virtio/virtio-snd.c
> @@ -134,6 +134,19 @@ virtio_snd_set_config(VirtIODevice *vdev, const
> uint8_t *config)
>      memcpy(&s->snd_conf, sndconfig, sizeof(s->snd_conf));
>  }
>
> +/*
> + * Get a specific stream from the virtio sound card device.
> + * Returns NULL if @stream_id is invalid or not allocated.
> + *
> + * @s: VirtIOSound device
> + * @stream_id: stream id
> + */
> +static VirtIOSoundPCMStream *virtio_snd_pcm_get_stream(VirtIOSound *s,
> +                                                       uint32_t stream_id)
> +{
> +    return stream_id >= s->snd_conf.streams ? NULL :
> s->pcm->streams[stream_id];
> +}
> +
>  /*
>   * Get params for a specific stream.
>   *
> @@ -147,6 +160,69 @@ static VirtIOSoundPCMParams
> *virtio_snd_pcm_get_params(VirtIOSound *s,
>          : s->pcm->pcm_params[stream_id];
>  }
>
> +/*
> + * Handle the VIRTIO_SND_R_PCM_INFO request.
> + * The function writes the info structs to the request element.
> + *
> + * @s: VirtIOSound device
> + * @cmd: The request command queue element from VirtIOSound cmdq field
> + */
> +static void virtio_snd_handle_pcm_info(VirtIOSound *s,
> +                                       virtio_snd_ctrl_command *cmd)
> +{
> +    virtio_snd_query_info req;
> +    VirtIOSoundPCMStream *stream = NULL;
> +    g_autofree virtio_snd_pcm_info *pcm_info = NULL;
> +    size_t sz = iov_to_buf(cmd->elem->out_sg,
> +                           cmd->elem->out_num,
> +                           0,
> +                           &req,
> +                           sizeof(req));
> +    if (sz != sizeof(virtio_snd_query_info)) {
> +        cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
> +        return;
> +    }
> +
> +    if (iov_size(cmd->elem->in_sg, cmd->elem->in_num) <
> +        sizeof(virtio_snd_hdr) + req.size * req.count) {
> +        error_report("pcm info: buffer too small, got: %lu, needed: %lu",
> +                iov_size(cmd->elem->in_sg, cmd->elem->in_num),
>


> +                sizeof(virtio_snd_pcm_info));
> +        cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
> +        return;
> +    }
> +
> +    pcm_info = g_new0(virtio_snd_pcm_info, req.count);
> +    for (uint32_t i = req.start_id; i < req.start_id + req.count; i++) {
> +        trace_virtio_snd_handle_pcm_info(i);
> +        stream = virtio_snd_pcm_get_stream(s, i);
> +
> +        if (!stream) {
> +            error_report("Invalid stream id: %"PRIu32, i);
> +            cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
> +            return;
> +        }
> +
> +        pcm_info[i - req.start_id].hdr.hda_fn_nid =
> stream->info.hdr.hda_fn_nid;
> +        pcm_info[i - req.start_id].features = stream->features;
> +        pcm_info[i - req.start_id].formats = stream->formats;
> +        pcm_info[i - req.start_id].rates = stream->rates;
> +        pcm_info[i - req.start_id].direction = stream->direction;
> +        pcm_info[i - req.start_id].channels_min = stream->channels_min;
> +        pcm_info[i - req.start_id].channels_max = stream->channels_max;
> +
> +        memset(&pcm_info[i].padding, 0, sizeof(pcm_info[i].padding));
> +    }
> +
> +    cmd->resp.code = VIRTIO_SND_S_OK;
> +
> +    iov_from_buf(cmd->elem->in_sg,
> +                 cmd->elem->in_num,
> +                 sizeof(virtio_snd_hdr),
> +                 pcm_info,
> +                 sizeof(virtio_snd_pcm_info) * req.count);
> +}
> +
>  /*
>   * Set the given stream params.
>   * Called by both virtio_snd_handle_pcm_set_params and during device
> @@ -358,6 +434,8 @@ process_cmd(VirtIOSound *s, virtio_snd_ctrl_command
> *cmd)
>          cmd->resp.code = VIRTIO_SND_S_NOT_SUPP;
>          break;
>      case VIRTIO_SND_R_PCM_INFO:
> +        virtio_snd_handle_pcm_info(s, cmd);
> +        break;
>      case VIRTIO_SND_R_PCM_SET_PARAMS:
>      case VIRTIO_SND_R_PCM_PREPARE:
>      case VIRTIO_SND_R_PCM_START:
> --
> 2.39.2
>
>
>
Marc-André Lureau July 25, 2023, 2:30 p.m. UTC | #2
On Thu, Jul 20, 2023 at 4:59 PM Emmanouil Pitsidianakis <
manos.pitsidianakis@linaro.org> wrote:

> Respond to the VIRTIO_SND_R_PCM_INFO control request with the parameters
> of each requested PCM stream.
>
> Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
> ---
>  hw/virtio/trace-events |  1 +
>  hw/virtio/virtio-snd.c | 78 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 79 insertions(+)
>
> diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
> index 8a223e36e9..3e619f778b 100644
> --- a/hw/virtio/trace-events
> +++ b/hw/virtio/trace-events
> @@ -164,6 +164,7 @@ virtio_snd_vm_state_stopped(void) "vm state stopped"
>  virtio_snd_realize(void *snd) "snd %p: realize"
>  virtio_snd_unrealize(void *snd) "snd %p: unrealize"
>  virtio_snd_handle_ctrl(void *vdev, void *vq) "snd %p: handle ctrl event
> for queue %p"
> +virtio_snd_handle_pcm_info(uint32_t stream) "VIRTIO_SND_R_PCM_INFO called
> for stream %"PRIu32
>  virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code msg val
> = %"PRIu32" == %s"
>  virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called"
>  virtio_snd_handle_event(void) "event queue callback called"
> diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c
> index ca09c937c7..3f8b46f372 100644
> --- a/hw/virtio/virtio-snd.c
> +++ b/hw/virtio/virtio-snd.c
> @@ -134,6 +134,19 @@ virtio_snd_set_config(VirtIODevice *vdev, const
> uint8_t *config)
>      memcpy(&s->snd_conf, sndconfig, sizeof(s->snd_conf));
>  }
>
> +/*
> + * Get a specific stream from the virtio sound card device.
> + * Returns NULL if @stream_id is invalid or not allocated.
> + *
> + * @s: VirtIOSound device
> + * @stream_id: stream id
> + */
> +static VirtIOSoundPCMStream *virtio_snd_pcm_get_stream(VirtIOSound *s,
> +                                                       uint32_t stream_id)
> +{
> +    return stream_id >= s->snd_conf.streams ? NULL :
> s->pcm->streams[stream_id];
> +}
> +
>  /*
>   * Get params for a specific stream.
>   *
> @@ -147,6 +160,69 @@ static VirtIOSoundPCMParams
> *virtio_snd_pcm_get_params(VirtIOSound *s,
>          : s->pcm->pcm_params[stream_id];
>  }
>
> +/*
> + * Handle the VIRTIO_SND_R_PCM_INFO request.
> + * The function writes the info structs to the request element.
> + *
> + * @s: VirtIOSound device
> + * @cmd: The request command queue element from VirtIOSound cmdq field
> + */
> +static void virtio_snd_handle_pcm_info(VirtIOSound *s,
> +                                       virtio_snd_ctrl_command *cmd)
> +{
> +    virtio_snd_query_info req;
> +    VirtIOSoundPCMStream *stream = NULL;
> +    g_autofree virtio_snd_pcm_info *pcm_info = NULL;
> +    size_t sz = iov_to_buf(cmd->elem->out_sg,
> +                           cmd->elem->out_num,
> +                           0,
> +                           &req,
> +                           sizeof(req));
> +    if (sz != sizeof(virtio_snd_query_info)) {
> +        cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
> +        return;
> +    }
> +
> +    if (iov_size(cmd->elem->in_sg, cmd->elem->in_num) <
> +        sizeof(virtio_snd_hdr) + req.size * req.count) {
> +        error_report("pcm info: buffer too small, got: %lu, needed: %lu",
> +                iov_size(cmd->elem->in_sg, cmd->elem->in_num),
> +                sizeof(virtio_snd_pcm_info));
>

../hw/virtio/virtio-snd.c: In function 'virtio_snd_handle_pcm_info':
../hw/virtio/virtio-snd.c:200:22: error: format '%lu' expects argument of
type 'long unsigned int', but argument 2 has type 'size_t' {aka 'long long
unsigned int'} [-Werror=format=]
  200 |         error_report("pcm info: buffer too small, got: %lu, needed:
%lu",
      |
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  201 |                 iov_size(cmd->elem->in_sg, cmd->elem->in_num),
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                 |
      |                 size_t {aka long long unsigned int}
../hw/virtio/virtio-snd.c:200:22: error: format '%lu' expects argument of
type 'long unsigned int', but argument 3 has type 'long long unsigned int'
[-Werror=format=]
  200 |         error_report("pcm info: buffer too small, got: %lu, needed:
%lu",
      |
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  201 |                 iov_size(cmd->elem->in_sg, cmd->elem->in_num),
  202 |                 sizeof(virtio_snd_pcm_info));
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                 |
      |                 long long unsigned int


> +        cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
> +        return;
> +    }
> +
> +    pcm_info = g_new0(virtio_snd_pcm_info, req.count);
> +    for (uint32_t i = req.start_id; i < req.start_id + req.count; i++) {
> +        trace_virtio_snd_handle_pcm_info(i);
> +        stream = virtio_snd_pcm_get_stream(s, i);
> +
> +        if (!stream) {
> +            error_report("Invalid stream id: %"PRIu32, i);
> +            cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
> +            return;
> +        }
> +
> +        pcm_info[i - req.start_id].hdr.hda_fn_nid =
> stream->info.hdr.hda_fn_nid;
> +        pcm_info[i - req.start_id].features = stream->features;
> +        pcm_info[i - req.start_id].formats = stream->formats;
> +        pcm_info[i - req.start_id].rates = stream->rates;
> +        pcm_info[i - req.start_id].direction = stream->direction;
> +        pcm_info[i - req.start_id].channels_min = stream->channels_min;
> +        pcm_info[i - req.start_id].channels_max = stream->channels_max;
> +
> +        memset(&pcm_info[i].padding, 0, sizeof(pcm_info[i].padding));
> +    }
> +
> +    cmd->resp.code = VIRTIO_SND_S_OK;
> +
> +    iov_from_buf(cmd->elem->in_sg,
> +                 cmd->elem->in_num,
> +                 sizeof(virtio_snd_hdr),
> +                 pcm_info,
> +                 sizeof(virtio_snd_pcm_info) * req.count);
> +}
> +
>  /*
>   * Set the given stream params.
>   * Called by both virtio_snd_handle_pcm_set_params and during device
> @@ -358,6 +434,8 @@ process_cmd(VirtIOSound *s, virtio_snd_ctrl_command
> *cmd)
>          cmd->resp.code = VIRTIO_SND_S_NOT_SUPP;
>          break;
>      case VIRTIO_SND_R_PCM_INFO:
> +        virtio_snd_handle_pcm_info(s, cmd);
> +        break;
>      case VIRTIO_SND_R_PCM_SET_PARAMS:
>      case VIRTIO_SND_R_PCM_PREPARE:
>      case VIRTIO_SND_R_PCM_START:
> --
> 2.39.2
>
>
>
Michael S. Tsirkin July 25, 2023, 2:46 p.m. UTC | #3
On Tue, Jul 25, 2023 at 06:29:58PM +0400, Marc-André Lureau wrote:
> 
> 
> On Thu, Jul 20, 2023 at 4:59 PM Emmanouil Pitsidianakis <
> manos.pitsidianakis@linaro.org> wrote:
> 
>     Respond to the VIRTIO_SND_R_PCM_INFO control request with the parameters
>     of each requested PCM stream.
> 
>     Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
>     ---
>      hw/virtio/trace-events |  1 +
>      hw/virtio/virtio-snd.c | 78 ++++++++++++++++++++++++++++++++++++++++++
>      2 files changed, 79 insertions(+)
> 
>     diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
>     index 8a223e36e9..3e619f778b 100644
>     --- a/hw/virtio/trace-events
>     +++ b/hw/virtio/trace-events
>     @@ -164,6 +164,7 @@ virtio_snd_vm_state_stopped(void) "vm state stopped"
>      virtio_snd_realize(void *snd) "snd %p: realize"
>      virtio_snd_unrealize(void *snd) "snd %p: unrealize"
>      virtio_snd_handle_ctrl(void *vdev, void *vq) "snd %p: handle ctrl event
>     for queue %p"
>     +virtio_snd_handle_pcm_info(uint32_t stream) "VIRTIO_SND_R_PCM_INFO called
>     for stream %"PRIu32
>      virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code msg val
>     = %"PRIu32" == %s"
>      virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called"
>      virtio_snd_handle_event(void) "event queue callback called"
>     diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c
>     index ca09c937c7..3f8b46f372 100644
>     --- a/hw/virtio/virtio-snd.c
>     +++ b/hw/virtio/virtio-snd.c
>     @@ -134,6 +134,19 @@ virtio_snd_set_config(VirtIODevice *vdev, const
>     uint8_t *config)
>          memcpy(&s->snd_conf, sndconfig, sizeof(s->snd_conf));
>      }
> 
>     +/*
>     + * Get a specific stream from the virtio sound card device.
>     + * Returns NULL if @stream_id is invalid or not allocated.
>     + *
>     + * @s: VirtIOSound device
>     + * @stream_id: stream id
>     + */
>     +static VirtIOSoundPCMStream *virtio_snd_pcm_get_stream(VirtIOSound *s,
>     +                                                       uint32_t stream_id)
>     +{
>     +    return stream_id >= s->snd_conf.streams ? NULL : s->pcm->streams
>     [stream_id];
>     +}
>     +
>      /*
>       * Get params for a specific stream.
>       *
>     @@ -147,6 +160,69 @@ static VirtIOSoundPCMParams *virtio_snd_pcm_get_params
>     (VirtIOSound *s,
>              : s->pcm->pcm_params[stream_id];
>      }
> 
>     +/*
>     + * Handle the VIRTIO_SND_R_PCM_INFO request.
>     + * The function writes the info structs to the request element.
>     + *
>     + * @s: VirtIOSound device
>     + * @cmd: The request command queue element from VirtIOSound cmdq field
>     + */
>     +static void virtio_snd_handle_pcm_info(VirtIOSound *s,
>     +                                       virtio_snd_ctrl_command *cmd)
>     +{
>     +    virtio_snd_query_info req;
>     +    VirtIOSoundPCMStream *stream = NULL;
>     +    g_autofree virtio_snd_pcm_info *pcm_info = NULL;
>     +    size_t sz = iov_to_buf(cmd->elem->out_sg,
>     +                           cmd->elem->out_num,
>     +                           0,
>     +                           &req,
>     +                           sizeof(req));
>     +    if (sz != sizeof(virtio_snd_query_info)) {
>     +        cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
>     +        return;
>     +    }
>     +
>     +    if (iov_size(cmd->elem->in_sg, cmd->elem->in_num) <
>     +        sizeof(virtio_snd_hdr) + req.size * req.count) {
>     +        error_report("pcm info: buffer too small, got: %lu, needed: %lu",
>     +                iov_size(cmd->elem->in_sg, cmd->elem->in_num),
> 
>  
> 
>     +                sizeof(virtio_snd_pcm_info));
>     +        cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
>     +        return;
>     +    }
>     +
>     +    pcm_info = g_new0(virtio_snd_pcm_info, req.count);
>     +    for (uint32_t i = req.start_id; i < req.start_id + req.count; i++) {
>     +        trace_virtio_snd_handle_pcm_info(i);
>     +        stream = virtio_snd_pcm_get_stream(s, i);
>     +
>     +        if (!stream) {
>     +            error_report("Invalid stream id: %"PRIu32, i);
>     +            cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
>     +            return;
>     +        }
>     +
>     +        pcm_info[i - req.start_id].hdr.hda_fn_nid = stream->
>     info.hdr.hda_fn_nid;
>     +        pcm_info[i - req.start_id].features = stream->features;
>     +        pcm_info[i - req.start_id].formats = stream->formats;
>     +        pcm_info[i - req.start_id].rates = stream->rates;
>     +        pcm_info[i - req.start_id].direction = stream->direction;
>     +        pcm_info[i - req.start_id].channels_min = stream->channels_min;
>     +        pcm_info[i - req.start_id].channels_max = stream->channels_max;
>     +
>     +        memset(&pcm_info[i].padding, 0, sizeof(pcm_info[i].padding));
>     +    }
>     +
>     +    cmd->resp.code = VIRTIO_SND_S_OK;
>     +
>     +    iov_from_buf(cmd->elem->in_sg,
>     +                 cmd->elem->in_num,
>     +                 sizeof(virtio_snd_hdr),
>     +                 pcm_info,
>     +                 sizeof(virtio_snd_pcm_info) * req.count);
>     +}
>     +
>      /*
>       * Set the given stream params.
>       * Called by both virtio_snd_handle_pcm_set_params and during device
>     @@ -358,6 +434,8 @@ process_cmd(VirtIOSound *s, virtio_snd_ctrl_command
>     *cmd)
>              cmd->resp.code = VIRTIO_SND_S_NOT_SUPP;
>              break;
>          case VIRTIO_SND_R_PCM_INFO:
>     +        virtio_snd_handle_pcm_info(s, cmd);
>     +        break;
>          case VIRTIO_SND_R_PCM_SET_PARAMS:
>          case VIRTIO_SND_R_PCM_PREPARE:
>          case VIRTIO_SND_R_PCM_START:
>     --
>     2.39.2
> 
> 
> 


Marc-André can you please stop with trying to use gmail web client?
Look here to see how it corrupts text by wrapping lines:
https://lore.kernel.org/all/CAJ+F1C+H+82cA=mhpju-2nxRSA3BWnWJmp4-pi+G=Lsri0oGTw@mail.gmail.com/

And please cut out irrelevant parts of message - I've no idea what you tried to say here.
Marc-André Lureau July 25, 2023, 2:54 p.m. UTC | #4
Hi

On Tue, Jul 25, 2023 at 6:47 PM Michael S. Tsirkin <mst@redhat.com> wrote:

> On Tue, Jul 25, 2023 at 06:29:58PM +0400, Marc-André Lureau wrote:
> >
> >
> > On Thu, Jul 20, 2023 at 4:59 PM Emmanouil Pitsidianakis <
> > manos.pitsidianakis@linaro.org> wrote:
> >
> >     Respond to the VIRTIO_SND_R_PCM_INFO control request with the
> parameters
> >     of each requested PCM stream.
> >
> >     Signed-off-by: Emmanouil Pitsidianakis <
> manos.pitsidianakis@linaro.org>
> >     ---
> >      hw/virtio/trace-events |  1 +
> >      hw/virtio/virtio-snd.c | 78
> ++++++++++++++++++++++++++++++++++++++++++
> >      2 files changed, 79 insertions(+)
> >
> >     diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
> >     index 8a223e36e9..3e619f778b 100644
> >     --- a/hw/virtio/trace-events
> >     +++ b/hw/virtio/trace-events
> >     @@ -164,6 +164,7 @@ virtio_snd_vm_state_stopped(void) "vm state
> stopped"
> >      virtio_snd_realize(void *snd) "snd %p: realize"
> >      virtio_snd_unrealize(void *snd) "snd %p: unrealize"
> >      virtio_snd_handle_ctrl(void *vdev, void *vq) "snd %p: handle ctrl
> event
> >     for queue %p"
> >     +virtio_snd_handle_pcm_info(uint32_t stream) "VIRTIO_SND_R_PCM_INFO
> called
> >     for stream %"PRIu32
> >      virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code
> msg val
> >     = %"PRIu32" == %s"
> >      virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called"
> >      virtio_snd_handle_event(void) "event queue callback called"
> >     diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c
> >     index ca09c937c7..3f8b46f372 100644
> >     --- a/hw/virtio/virtio-snd.c
> >     +++ b/hw/virtio/virtio-snd.c
> >     @@ -134,6 +134,19 @@ virtio_snd_set_config(VirtIODevice *vdev, const
> >     uint8_t *config)
> >          memcpy(&s->snd_conf, sndconfig, sizeof(s->snd_conf));
> >      }
> >
> >     +/*
> >     + * Get a specific stream from the virtio sound card device.
> >     + * Returns NULL if @stream_id is invalid or not allocated.
> >     + *
> >     + * @s: VirtIOSound device
> >     + * @stream_id: stream id
> >     + */
> >     +static VirtIOSoundPCMStream *virtio_snd_pcm_get_stream(VirtIOSound
> *s,
> >     +                                                       uint32_t
> stream_id)
> >     +{
> >     +    return stream_id >= s->snd_conf.streams ? NULL : s->pcm->streams
> >     [stream_id];
> >     +}
> >     +
> >      /*
> >       * Get params for a specific stream.
> >       *
> >     @@ -147,6 +160,69 @@ static VirtIOSoundPCMParams
> *virtio_snd_pcm_get_params
> >     (VirtIOSound *s,
> >              : s->pcm->pcm_params[stream_id];
> >      }
> >
> >     +/*
> >     + * Handle the VIRTIO_SND_R_PCM_INFO request.
> >     + * The function writes the info structs to the request element.
> >     + *
> >     + * @s: VirtIOSound device
> >     + * @cmd: The request command queue element from VirtIOSound cmdq
> field
> >     + */
> >     +static void virtio_snd_handle_pcm_info(VirtIOSound *s,
> >     +                                       virtio_snd_ctrl_command *cmd)
> >     +{
> >     +    virtio_snd_query_info req;
> >     +    VirtIOSoundPCMStream *stream = NULL;
> >     +    g_autofree virtio_snd_pcm_info *pcm_info = NULL;
> >     +    size_t sz = iov_to_buf(cmd->elem->out_sg,
> >     +                           cmd->elem->out_num,
> >     +                           0,
> >     +                           &req,
> >     +                           sizeof(req));
> >     +    if (sz != sizeof(virtio_snd_query_info)) {
> >     +        cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
> >     +        return;
> >     +    }
> >     +
> >     +    if (iov_size(cmd->elem->in_sg, cmd->elem->in_num) <
> >     +        sizeof(virtio_snd_hdr) + req.size * req.count) {
> >     +        error_report("pcm info: buffer too small, got: %lu, needed:
> %lu",
> >     +                iov_size(cmd->elem->in_sg, cmd->elem->in_num),
> >
> >
> >
> >     +                sizeof(virtio_snd_pcm_info));
> >     +        cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
> >     +        return;
> >     +    }
> >     +
> >     +    pcm_info = g_new0(virtio_snd_pcm_info, req.count);
> >     +    for (uint32_t i = req.start_id; i < req.start_id + req.count;
> i++) {
> >     +        trace_virtio_snd_handle_pcm_info(i);
> >     +        stream = virtio_snd_pcm_get_stream(s, i);
> >     +
> >     +        if (!stream) {
> >     +            error_report("Invalid stream id: %"PRIu32, i);
> >     +            cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
> >     +            return;
> >     +        }
> >     +
> >     +        pcm_info[i - req.start_id].hdr.hda_fn_nid = stream->
> >     info.hdr.hda_fn_nid;
> >     +        pcm_info[i - req.start_id].features = stream->features;
> >     +        pcm_info[i - req.start_id].formats = stream->formats;
> >     +        pcm_info[i - req.start_id].rates = stream->rates;
> >     +        pcm_info[i - req.start_id].direction = stream->direction;
> >     +        pcm_info[i - req.start_id].channels_min =
> stream->channels_min;
> >     +        pcm_info[i - req.start_id].channels_max =
> stream->channels_max;
> >     +
> >     +        memset(&pcm_info[i].padding, 0,
> sizeof(pcm_info[i].padding));
> >     +    }
> >     +
> >     +    cmd->resp.code = VIRTIO_SND_S_OK;
> >     +
> >     +    iov_from_buf(cmd->elem->in_sg,
> >     +                 cmd->elem->in_num,
> >     +                 sizeof(virtio_snd_hdr),
> >     +                 pcm_info,
> >     +                 sizeof(virtio_snd_pcm_info) * req.count);
> >     +}
> >     +
> >      /*
> >       * Set the given stream params.
> >       * Called by both virtio_snd_handle_pcm_set_params and during device
> >     @@ -358,6 +434,8 @@ process_cmd(VirtIOSound *s,
> virtio_snd_ctrl_command
> >     *cmd)
> >              cmd->resp.code = VIRTIO_SND_S_NOT_SUPP;
> >              break;
> >          case VIRTIO_SND_R_PCM_INFO:
> >     +        virtio_snd_handle_pcm_info(s, cmd);
> >     +        break;
> >          case VIRTIO_SND_R_PCM_SET_PARAMS:
> >          case VIRTIO_SND_R_PCM_PREPARE:
> >          case VIRTIO_SND_R_PCM_START:
> >     --
> >     2.39.2
> >
> >
> >
>
>
> Marc-André can you please stop with trying to use gmail web client?
>

Trying? I think I have almost exclusively used it over the past 15y or so :)


> Look here to see how it corrupts text by wrapping lines:
>
> https://lore.kernel.org/all/CAJ+F1C+H+82cA=mhpju-2nxRSA3BWnWJmp4-pi+G=Lsri0oGTw@mail.gmail.com/
>
> And please cut out irrelevant parts of message - I've no idea what you
> tried to say here.
>

that was my mistake, I sent it too quickly.. it happens.
Michael S. Tsirkin July 25, 2023, 4:15 p.m. UTC | #5
On Tue, Jul 25, 2023 at 06:54:56PM +0400, Marc-André Lureau wrote:
> 
>     Marc-André can you please stop with trying to use gmail web client?
> 
> 
> Trying? I think I have almost exclusively used it over the past 15y or so :)
>  

Then find a way make it not wrap lines.  The result of corrupted text is
people giving up in disgust and asking everyone to switch to gitlab
or slack or whatnot.
diff mbox series

Patch

diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 8a223e36e9..3e619f778b 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -164,6 +164,7 @@  virtio_snd_vm_state_stopped(void) "vm state stopped"
 virtio_snd_realize(void *snd) "snd %p: realize"
 virtio_snd_unrealize(void *snd) "snd %p: unrealize"
 virtio_snd_handle_ctrl(void *vdev, void *vq) "snd %p: handle ctrl event for queue %p"
+virtio_snd_handle_pcm_info(uint32_t stream) "VIRTIO_SND_R_PCM_INFO called for stream %"PRIu32
 virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code msg val = %"PRIu32" == %s"
 virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called"
 virtio_snd_handle_event(void) "event queue callback called"
diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c
index ca09c937c7..3f8b46f372 100644
--- a/hw/virtio/virtio-snd.c
+++ b/hw/virtio/virtio-snd.c
@@ -134,6 +134,19 @@  virtio_snd_set_config(VirtIODevice *vdev, const uint8_t *config)
     memcpy(&s->snd_conf, sndconfig, sizeof(s->snd_conf));
 }
 
+/*
+ * Get a specific stream from the virtio sound card device.
+ * Returns NULL if @stream_id is invalid or not allocated.
+ *
+ * @s: VirtIOSound device
+ * @stream_id: stream id
+ */
+static VirtIOSoundPCMStream *virtio_snd_pcm_get_stream(VirtIOSound *s,
+                                                       uint32_t stream_id)
+{
+    return stream_id >= s->snd_conf.streams ? NULL : s->pcm->streams[stream_id];
+}
+
 /*
  * Get params for a specific stream.
  *
@@ -147,6 +160,69 @@  static VirtIOSoundPCMParams *virtio_snd_pcm_get_params(VirtIOSound *s,
         : s->pcm->pcm_params[stream_id];
 }
 
+/*
+ * Handle the VIRTIO_SND_R_PCM_INFO request.
+ * The function writes the info structs to the request element.
+ *
+ * @s: VirtIOSound device
+ * @cmd: The request command queue element from VirtIOSound cmdq field
+ */
+static void virtio_snd_handle_pcm_info(VirtIOSound *s,
+                                       virtio_snd_ctrl_command *cmd)
+{
+    virtio_snd_query_info req;
+    VirtIOSoundPCMStream *stream = NULL;
+    g_autofree virtio_snd_pcm_info *pcm_info = NULL;
+    size_t sz = iov_to_buf(cmd->elem->out_sg,
+                           cmd->elem->out_num,
+                           0,
+                           &req,
+                           sizeof(req));
+    if (sz != sizeof(virtio_snd_query_info)) {
+        cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
+        return;
+    }
+
+    if (iov_size(cmd->elem->in_sg, cmd->elem->in_num) <
+        sizeof(virtio_snd_hdr) + req.size * req.count) {
+        error_report("pcm info: buffer too small, got: %lu, needed: %lu",
+                iov_size(cmd->elem->in_sg, cmd->elem->in_num),
+                sizeof(virtio_snd_pcm_info));
+        cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
+        return;
+    }
+
+    pcm_info = g_new0(virtio_snd_pcm_info, req.count);
+    for (uint32_t i = req.start_id; i < req.start_id + req.count; i++) {
+        trace_virtio_snd_handle_pcm_info(i);
+        stream = virtio_snd_pcm_get_stream(s, i);
+
+        if (!stream) {
+            error_report("Invalid stream id: %"PRIu32, i);
+            cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
+            return;
+        }
+
+        pcm_info[i - req.start_id].hdr.hda_fn_nid = stream->info.hdr.hda_fn_nid;
+        pcm_info[i - req.start_id].features = stream->features;
+        pcm_info[i - req.start_id].formats = stream->formats;
+        pcm_info[i - req.start_id].rates = stream->rates;
+        pcm_info[i - req.start_id].direction = stream->direction;
+        pcm_info[i - req.start_id].channels_min = stream->channels_min;
+        pcm_info[i - req.start_id].channels_max = stream->channels_max;
+
+        memset(&pcm_info[i].padding, 0, sizeof(pcm_info[i].padding));
+    }
+
+    cmd->resp.code = VIRTIO_SND_S_OK;
+
+    iov_from_buf(cmd->elem->in_sg,
+                 cmd->elem->in_num,
+                 sizeof(virtio_snd_hdr),
+                 pcm_info,
+                 sizeof(virtio_snd_pcm_info) * req.count);
+}
+
 /*
  * Set the given stream params.
  * Called by both virtio_snd_handle_pcm_set_params and during device
@@ -358,6 +434,8 @@  process_cmd(VirtIOSound *s, virtio_snd_ctrl_command *cmd)
         cmd->resp.code = VIRTIO_SND_S_NOT_SUPP;
         break;
     case VIRTIO_SND_R_PCM_INFO:
+        virtio_snd_handle_pcm_info(s, cmd);
+        break;
     case VIRTIO_SND_R_PCM_SET_PARAMS:
     case VIRTIO_SND_R_PCM_PREPARE:
     case VIRTIO_SND_R_PCM_START: