Message ID | f267d41957025b3849324f459a8ed476aa89f828.1689857559.git.manos.pitsidianakis@linaro.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add VIRTIO sound card | expand |
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 > > >
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 > > >
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.
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.
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 --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:
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(+)