2 * VIRTIO Sound Device conforming to
4 * "Virtual I/O Device (VIRTIO) Version 1.2
5 * Committee Specification Draft 01
8 * <https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-52900014>
10 * Copyright (c) 2023 Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
11 * Copyright (C) 2019 OpenSynergy GmbH
13 * This work is licensed under the terms of the GNU GPL, version 2 or
14 * (at your option) any later version. See the COPYING file in the
15 * top-level directory.
18 #include "qemu/osdep.h"
21 #include "qemu/error-report.h"
22 #include "include/qemu/lockable.h"
23 #include "sysemu/runstate.h"
25 #include "qapi/error.h"
26 #include "hw/audio/virtio-snd.h"
27 #include "hw/core/cpu.h"
29 #define VIRTIO_SOUND_VM_VERSION 1
30 #define VIRTIO_SOUND_JACK_DEFAULT 0
31 #define VIRTIO_SOUND_STREAM_DEFAULT 2
32 #define VIRTIO_SOUND_CHMAP_DEFAULT 0
33 #define VIRTIO_SOUND_HDA_FN_NID 0
35 static void virtio_snd_pcm_out_cb(void *data
, int available
);
36 static void virtio_snd_process_cmdq(VirtIOSound
*s
);
37 static void virtio_snd_pcm_flush(VirtIOSoundPCMStream
*stream
);
38 static void virtio_snd_pcm_in_cb(void *data
, int available
);
39 static void virtio_snd_unrealize(DeviceState
*dev
);
41 static uint32_t supported_formats
= BIT(VIRTIO_SND_PCM_FMT_S8
)
42 | BIT(VIRTIO_SND_PCM_FMT_U8
)
43 | BIT(VIRTIO_SND_PCM_FMT_S16
)
44 | BIT(VIRTIO_SND_PCM_FMT_U16
)
45 | BIT(VIRTIO_SND_PCM_FMT_S32
)
46 | BIT(VIRTIO_SND_PCM_FMT_U32
)
47 | BIT(VIRTIO_SND_PCM_FMT_FLOAT
);
49 static uint32_t supported_rates
= BIT(VIRTIO_SND_PCM_RATE_5512
)
50 | BIT(VIRTIO_SND_PCM_RATE_8000
)
51 | BIT(VIRTIO_SND_PCM_RATE_11025
)
52 | BIT(VIRTIO_SND_PCM_RATE_16000
)
53 | BIT(VIRTIO_SND_PCM_RATE_22050
)
54 | BIT(VIRTIO_SND_PCM_RATE_32000
)
55 | BIT(VIRTIO_SND_PCM_RATE_44100
)
56 | BIT(VIRTIO_SND_PCM_RATE_48000
)
57 | BIT(VIRTIO_SND_PCM_RATE_64000
)
58 | BIT(VIRTIO_SND_PCM_RATE_88200
)
59 | BIT(VIRTIO_SND_PCM_RATE_96000
)
60 | BIT(VIRTIO_SND_PCM_RATE_176400
)
61 | BIT(VIRTIO_SND_PCM_RATE_192000
)
62 | BIT(VIRTIO_SND_PCM_RATE_384000
);
64 static const VMStateDescription vmstate_virtio_snd_device
= {
65 .name
= TYPE_VIRTIO_SND
,
66 .version_id
= VIRTIO_SOUND_VM_VERSION
,
67 .minimum_version_id
= VIRTIO_SOUND_VM_VERSION
,
70 static const VMStateDescription vmstate_virtio_snd
= {
71 .name
= TYPE_VIRTIO_SND
,
73 .minimum_version_id
= VIRTIO_SOUND_VM_VERSION
,
74 .version_id
= VIRTIO_SOUND_VM_VERSION
,
75 .fields
= (VMStateField
[]) {
76 VMSTATE_VIRTIO_DEVICE
,
81 static Property virtio_snd_properties
[] = {
82 DEFINE_AUDIO_PROPERTIES(VirtIOSound
, card
),
83 DEFINE_PROP_UINT32("jacks", VirtIOSound
, snd_conf
.jacks
,
84 VIRTIO_SOUND_JACK_DEFAULT
),
85 DEFINE_PROP_UINT32("streams", VirtIOSound
, snd_conf
.streams
,
86 VIRTIO_SOUND_STREAM_DEFAULT
),
87 DEFINE_PROP_UINT32("chmaps", VirtIOSound
, snd_conf
.chmaps
,
88 VIRTIO_SOUND_CHMAP_DEFAULT
),
89 DEFINE_PROP_END_OF_LIST(),
93 virtio_snd_get_config(VirtIODevice
*vdev
, uint8_t *config
)
95 VirtIOSound
*s
= VIRTIO_SND(vdev
);
96 virtio_snd_config
*sndconfig
=
97 (virtio_snd_config
*)config
;
98 trace_virtio_snd_get_config(vdev
,
103 memcpy(sndconfig
, &s
->snd_conf
, sizeof(s
->snd_conf
));
104 cpu_to_le32s(&sndconfig
->jacks
);
105 cpu_to_le32s(&sndconfig
->streams
);
106 cpu_to_le32s(&sndconfig
->chmaps
);
111 virtio_snd_set_config(VirtIODevice
*vdev
, const uint8_t *config
)
113 VirtIOSound
*s
= VIRTIO_SND(vdev
);
114 const virtio_snd_config
*sndconfig
=
115 (const virtio_snd_config
*)config
;
118 trace_virtio_snd_set_config(vdev
,
126 memcpy(&s
->snd_conf
, sndconfig
, sizeof(virtio_snd_config
));
127 le32_to_cpus(&s
->snd_conf
.jacks
);
128 le32_to_cpus(&s
->snd_conf
.streams
);
129 le32_to_cpus(&s
->snd_conf
.chmaps
);
134 virtio_snd_pcm_buffer_free(VirtIOSoundPCMBuffer
*buffer
)
136 g_free(buffer
->elem
);
141 virtio_snd_ctrl_cmd_free(virtio_snd_ctrl_command
*cmd
)
148 * Get a specific stream from the virtio sound card device.
149 * Returns NULL if @stream_id is invalid or not allocated.
151 * @s: VirtIOSound device
152 * @stream_id: stream id
154 static VirtIOSoundPCMStream
*virtio_snd_pcm_get_stream(VirtIOSound
*s
,
157 return stream_id
>= s
->snd_conf
.streams
? NULL
:
158 s
->pcm
->streams
[stream_id
];
162 * Get params for a specific stream.
164 * @s: VirtIOSound device
165 * @stream_id: stream id
167 static virtio_snd_pcm_set_params
*virtio_snd_pcm_get_params(VirtIOSound
*s
,
170 return stream_id
>= s
->snd_conf
.streams
? NULL
171 : &s
->pcm
->pcm_params
[stream_id
];
175 * Handle the VIRTIO_SND_R_PCM_INFO request.
176 * The function writes the info structs to the request element.
178 * @s: VirtIOSound device
179 * @cmd: The request command queue element from VirtIOSound cmdq field
181 static void virtio_snd_handle_pcm_info(VirtIOSound
*s
,
182 virtio_snd_ctrl_command
*cmd
)
184 uint32_t stream_id
, start_id
, count
, size
;
185 virtio_snd_pcm_info val
;
186 virtio_snd_query_info req
;
187 VirtIOSoundPCMStream
*stream
= NULL
;
188 g_autofree virtio_snd_pcm_info
*pcm_info
= NULL
;
189 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
193 sizeof(virtio_snd_query_info
));
195 if (msg_sz
!= sizeof(virtio_snd_query_info
)) {
197 * TODO: do we need to set DEVICE_NEEDS_RESET?
199 qemu_log_mask(LOG_GUEST_ERROR
,
200 "%s: virtio-snd command size incorrect %zu vs \
201 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_query_info
));
202 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
206 start_id
= le32_to_cpu(req
.start_id
);
207 count
= le32_to_cpu(req
.count
);
208 size
= le32_to_cpu(req
.size
);
210 if (iov_size(cmd
->elem
->in_sg
, cmd
->elem
->in_num
) <
211 sizeof(virtio_snd_hdr
) + size
* count
) {
213 * TODO: do we need to set DEVICE_NEEDS_RESET?
215 error_report("pcm info: buffer too small, got: %zu, needed: %zu",
216 iov_size(cmd
->elem
->in_sg
, cmd
->elem
->in_num
),
217 sizeof(virtio_snd_pcm_info
));
218 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
222 pcm_info
= g_new0(virtio_snd_pcm_info
, count
);
223 for (uint32_t i
= 0; i
< count
; i
++) {
224 stream_id
= i
+ start_id
;
225 trace_virtio_snd_handle_pcm_info(stream_id
);
226 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
228 error_report("Invalid stream id: %"PRIu32
, stream_id
);
229 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
233 val
.hdr
.hda_fn_nid
= cpu_to_le32(val
.hdr
.hda_fn_nid
);
234 val
.features
= cpu_to_le32(val
.features
);
235 val
.formats
= cpu_to_le64(val
.formats
);
236 val
.rates
= cpu_to_le64(val
.rates
);
238 * 5.14.6.6.2.1 Device Requirements: Stream Information The device MUST
239 * NOT set undefined feature, format, rate and direction values. The
240 * device MUST initialize the padding bytes to 0.
243 memset(&pcm_info
[i
].padding
, 0, 5);
246 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
247 iov_from_buf(cmd
->elem
->in_sg
,
249 sizeof(virtio_snd_hdr
),
251 sizeof(virtio_snd_pcm_info
) * count
);
255 * Set the given stream params.
256 * Called by both virtio_snd_handle_pcm_set_params and during device
258 * Returns the response status code. (VIRTIO_SND_S_*).
260 * @s: VirtIOSound device
261 * @params: The PCM params as defined in the virtio specification
264 uint32_t virtio_snd_set_pcm_params(VirtIOSound
*s
,
266 virtio_snd_pcm_set_params
*params
)
268 virtio_snd_pcm_set_params
*st_params
;
270 if (stream_id
>= s
->snd_conf
.streams
|| s
->pcm
->pcm_params
== NULL
) {
272 * TODO: do we need to set DEVICE_NEEDS_RESET?
274 virtio_error(VIRTIO_DEVICE(s
), "Streams have not been initialized.\n");
275 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
278 st_params
= virtio_snd_pcm_get_params(s
, stream_id
);
280 if (params
->channels
< 1 || params
->channels
> AUDIO_MAX_CHANNELS
) {
281 error_report("Number of channels is not supported.");
282 return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
284 if (!(supported_formats
& BIT(params
->format
))) {
285 error_report("Stream format is not supported.");
286 return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
288 if (!(supported_rates
& BIT(params
->rate
))) {
289 error_report("Stream rate is not supported.");
290 return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
293 st_params
->buffer_bytes
= le32_to_cpu(params
->buffer_bytes
);
294 st_params
->period_bytes
= le32_to_cpu(params
->period_bytes
);
295 st_params
->features
= le32_to_cpu(params
->features
);
296 /* the following are uint8_t, so there's no need to bswap the values. */
297 st_params
->channels
= params
->channels
;
298 st_params
->format
= params
->format
;
299 st_params
->rate
= params
->rate
;
301 return cpu_to_le32(VIRTIO_SND_S_OK
);
305 * Handles the VIRTIO_SND_R_PCM_SET_PARAMS request.
307 * @s: VirtIOSound device
308 * @cmd: The request command queue element from VirtIOSound cmdq field
310 static void virtio_snd_handle_pcm_set_params(VirtIOSound
*s
,
311 virtio_snd_ctrl_command
*cmd
)
313 virtio_snd_pcm_set_params req
= { 0 };
315 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
319 sizeof(virtio_snd_pcm_set_params
));
321 if (msg_sz
!= sizeof(virtio_snd_pcm_set_params
)) {
323 * TODO: do we need to set DEVICE_NEEDS_RESET?
325 qemu_log_mask(LOG_GUEST_ERROR
,
326 "%s: virtio-snd command size incorrect %zu vs \
327 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_pcm_set_params
));
328 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
331 stream_id
= le32_to_cpu(req
.hdr
.stream_id
);
332 trace_virtio_snd_handle_pcm_set_params(stream_id
);
333 cmd
->resp
.code
= virtio_snd_set_pcm_params(s
, stream_id
, &req
);
337 * Get a QEMU Audiosystem compatible format value from a VIRTIO_SND_PCM_FMT_*
339 static AudioFormat
virtio_snd_get_qemu_format(uint32_t format
)
342 case VIRTIO_SND_PCM_FMT_##FMT: \
343 return AUDIO_FORMAT_##FMT;
352 case VIRTIO_SND_PCM_FMT_FLOAT
:
353 return AUDIO_FORMAT_F32
;
355 g_assert_not_reached();
362 * Get a QEMU Audiosystem compatible frequency value from a
363 * VIRTIO_SND_PCM_RATE_*
365 static uint32_t virtio_snd_get_qemu_freq(uint32_t rate
)
368 case VIRTIO_SND_PCM_RATE_##RATE: \
387 g_assert_not_reached();
394 * Get QEMU Audiosystem compatible audsettings from virtio based pcm stream
397 static void virtio_snd_get_qemu_audsettings(audsettings
*as
,
398 virtio_snd_pcm_set_params
*params
)
400 as
->nchannels
= MIN(AUDIO_MAX_CHANNELS
, params
->channels
);
401 as
->fmt
= virtio_snd_get_qemu_format(params
->format
);
402 as
->freq
= virtio_snd_get_qemu_freq(params
->rate
);
403 as
->endianness
= target_words_bigendian() ? 1 : 0;
407 * Close a stream and free all its resources.
409 * @stream: VirtIOSoundPCMStream *stream
411 static void virtio_snd_pcm_close(VirtIOSoundPCMStream
*stream
)
414 virtio_snd_pcm_flush(stream
);
415 if (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) {
416 AUD_close_out(&stream
->pcm
->snd
->card
, stream
->voice
.out
);
417 stream
->voice
.out
= NULL
;
418 } else if (stream
->info
.direction
== VIRTIO_SND_D_INPUT
) {
419 AUD_close_in(&stream
->pcm
->snd
->card
, stream
->voice
.in
);
420 stream
->voice
.in
= NULL
;
426 * Prepares a VirtIOSound card stream.
427 * Returns the response status code. (VIRTIO_SND_S_*).
429 * @s: VirtIOSound device
430 * @stream_id: stream id
432 static uint32_t virtio_snd_pcm_prepare(VirtIOSound
*s
, uint32_t stream_id
)
435 virtio_snd_pcm_set_params
*params
;
436 VirtIOSoundPCMStream
*stream
;
438 if (s
->pcm
->streams
== NULL
||
439 s
->pcm
->pcm_params
== NULL
||
440 stream_id
>= s
->snd_conf
.streams
) {
441 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
444 params
= virtio_snd_pcm_get_params(s
, stream_id
);
445 if (params
== NULL
) {
446 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
449 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
450 if (stream
== NULL
) {
451 stream
= g_new0(VirtIOSoundPCMStream
, 1);
452 stream
->active
= false;
453 stream
->id
= stream_id
;
454 stream
->pcm
= s
->pcm
;
456 qemu_mutex_init(&stream
->queue_mutex
);
457 QSIMPLEQ_INIT(&stream
->queue
);
458 QSIMPLEQ_INIT(&stream
->invalid
);
461 * stream_id >= s->snd_conf.streams was checked before so this is
464 s
->pcm
->streams
[stream_id
] = stream
;
467 virtio_snd_get_qemu_audsettings(&as
, params
);
468 stream
->info
.direction
= stream_id
< s
->snd_conf
.streams
/ 2 +
469 (s
->snd_conf
.streams
& 1) ? VIRTIO_SND_D_OUTPUT
: VIRTIO_SND_D_INPUT
;
470 stream
->info
.hdr
.hda_fn_nid
= VIRTIO_SOUND_HDA_FN_NID
;
471 stream
->info
.features
= 0;
472 stream
->info
.channels_min
= 1;
473 stream
->info
.channels_max
= as
.nchannels
;
474 stream
->info
.formats
= supported_formats
;
475 stream
->info
.rates
= supported_rates
;
476 stream
->params
= *params
;
478 stream
->positions
[0] = VIRTIO_SND_CHMAP_FL
;
479 stream
->positions
[1] = VIRTIO_SND_CHMAP_FR
;
482 if (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) {
483 stream
->voice
.out
= AUD_open_out(&s
->card
,
487 virtio_snd_pcm_out_cb
,
489 AUD_set_volume_out(stream
->voice
.out
, 0, 255, 255);
491 stream
->voice
.in
= AUD_open_in(&s
->card
,
495 virtio_snd_pcm_in_cb
,
497 AUD_set_volume_in(stream
->voice
.in
, 0, 255, 255);
500 return cpu_to_le32(VIRTIO_SND_S_OK
);
503 static const char *print_code(uint32_t code
)
506 case VIRTIO_SND_R_##CODE: \
507 return "VIRTIO_SND_R_"#CODE
513 CASE(PCM_SET_PARAMS
);
520 return "invalid code";
527 * Handles VIRTIO_SND_R_PCM_PREPARE.
529 * @s: VirtIOSound device
530 * @cmd: The request command queue element from VirtIOSound cmdq field
532 static void virtio_snd_handle_pcm_prepare(VirtIOSound
*s
,
533 virtio_snd_ctrl_command
*cmd
)
536 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
538 sizeof(virtio_snd_hdr
),
542 stream_id
= le32_to_cpu(stream_id
);
543 cmd
->resp
.code
= msg_sz
== sizeof(stream_id
)
544 ? virtio_snd_pcm_prepare(s
, stream_id
)
545 : cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
549 * Handles VIRTIO_SND_R_PCM_START.
551 * @s: VirtIOSound device
552 * @cmd: The request command queue element from VirtIOSound cmdq field
553 * @start: whether to start or stop the device
555 static void virtio_snd_handle_pcm_start_stop(VirtIOSound
*s
,
556 virtio_snd_ctrl_command
*cmd
,
559 VirtIOSoundPCMStream
*stream
;
560 virtio_snd_pcm_hdr req
;
562 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
566 sizeof(virtio_snd_pcm_hdr
));
568 if (msg_sz
!= sizeof(virtio_snd_pcm_hdr
)) {
569 qemu_log_mask(LOG_GUEST_ERROR
,
570 "%s: virtio-snd command size incorrect %zu vs \
571 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_pcm_hdr
));
572 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
576 stream_id
= le32_to_cpu(req
.stream_id
);
577 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
578 trace_virtio_snd_handle_pcm_start_stop(start
? "VIRTIO_SND_R_PCM_START" :
579 "VIRTIO_SND_R_PCM_STOP", stream_id
);
581 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
583 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
584 stream
->active
= start
;
586 if (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) {
587 AUD_set_active_out(stream
->voice
.out
, start
);
589 AUD_set_active_in(stream
->voice
.in
, start
);
592 error_report("Invalid stream id: %"PRIu32
, stream_id
);
593 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
596 stream
->active
= start
;
600 * Returns the number of I/O messages that are being processed.
602 * @stream: VirtIOSoundPCMStream
604 static size_t virtio_snd_pcm_get_io_msgs_count(VirtIOSoundPCMStream
*stream
)
606 VirtIOSoundPCMBuffer
*buffer
, *next
;
609 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
610 QSIMPLEQ_FOREACH_SAFE(buffer
, &stream
->queue
, entry
, next
) {
613 QSIMPLEQ_FOREACH_SAFE(buffer
, &stream
->invalid
, entry
, next
) {
621 * Handles VIRTIO_SND_R_PCM_RELEASE.
623 * @s: VirtIOSound device
624 * @cmd: The request command queue element from VirtIOSound cmdq field
626 static void virtio_snd_handle_pcm_release(VirtIOSound
*s
,
627 virtio_snd_ctrl_command
*cmd
)
630 VirtIOSoundPCMStream
*stream
;
631 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
633 sizeof(virtio_snd_hdr
),
637 if (msg_sz
!= sizeof(stream_id
)) {
639 * TODO: do we need to set DEVICE_NEEDS_RESET?
641 qemu_log_mask(LOG_GUEST_ERROR
,
642 "%s: virtio-snd command size incorrect %zu vs \
643 %zu\n", __func__
, msg_sz
, sizeof(stream_id
));
644 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
648 stream_id
= le32_to_cpu(stream_id
);
649 trace_virtio_snd_handle_pcm_release(stream_id
);
650 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
651 if (stream
== NULL
) {
653 * TODO: do we need to set DEVICE_NEEDS_RESET?
655 error_report("already released stream %"PRIu32
, stream_id
);
656 virtio_error(VIRTIO_DEVICE(s
),
657 "already released stream %"PRIu32
,
659 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
663 if (virtio_snd_pcm_get_io_msgs_count(stream
)) {
665 * virtio-v1.2-csd01, 5.14.6.6.5.1,
666 * Device Requirements: Stream Release
668 * - The device MUST complete all pending I/O messages for the
669 * specified stream ID.
670 * - The device MUST NOT complete the control request while there
671 * are pending I/O messages for the specified stream ID.
673 trace_virtio_snd_pcm_stream_flush(stream_id
);
674 virtio_snd_pcm_flush(stream
);
677 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
681 * The actual processing done in virtio_snd_process_cmdq().
683 * @s: VirtIOSound device
684 * @cmd: control command request
687 process_cmd(VirtIOSound
*s
, virtio_snd_ctrl_command
*cmd
)
690 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
694 sizeof(virtio_snd_hdr
));
696 if (msg_sz
!= sizeof(virtio_snd_hdr
)) {
698 * TODO: do we need to set DEVICE_NEEDS_RESET?
700 qemu_log_mask(LOG_GUEST_ERROR
,
701 "%s: virtio-snd command size incorrect %zu vs \
702 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_hdr
));
706 code
= le32_to_cpu(cmd
->ctrl
.code
);
708 trace_virtio_snd_handle_code(code
, print_code(code
));
711 case VIRTIO_SND_R_JACK_INFO
:
712 case VIRTIO_SND_R_JACK_REMAP
:
713 qemu_log_mask(LOG_UNIMP
,
714 "virtio_snd: jack functionality is unimplemented.\n");
715 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
717 case VIRTIO_SND_R_PCM_INFO
:
718 virtio_snd_handle_pcm_info(s
, cmd
);
720 case VIRTIO_SND_R_PCM_START
:
721 virtio_snd_handle_pcm_start_stop(s
, cmd
, true);
723 case VIRTIO_SND_R_PCM_STOP
:
724 virtio_snd_handle_pcm_start_stop(s
, cmd
, false);
726 case VIRTIO_SND_R_PCM_SET_PARAMS
:
727 virtio_snd_handle_pcm_set_params(s
, cmd
);
729 case VIRTIO_SND_R_PCM_PREPARE
:
730 virtio_snd_handle_pcm_prepare(s
, cmd
);
732 case VIRTIO_SND_R_PCM_RELEASE
:
733 virtio_snd_handle_pcm_release(s
, cmd
);
735 case VIRTIO_SND_R_CHMAP_INFO
:
736 qemu_log_mask(LOG_UNIMP
,
737 "virtio_snd: chmap info functionality is unimplemented.\n");
738 trace_virtio_snd_handle_chmap_info();
739 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
743 error_report("virtio snd header not recognized: %"PRIu32
, code
);
744 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
747 iov_from_buf(cmd
->elem
->in_sg
,
751 sizeof(virtio_snd_hdr
));
752 virtqueue_push(cmd
->vq
, cmd
->elem
, sizeof(virtio_snd_hdr
));
753 virtio_notify(VIRTIO_DEVICE(s
), cmd
->vq
);
757 * Consume all elements in command queue.
759 * @s: VirtIOSound device
761 static void virtio_snd_process_cmdq(VirtIOSound
*s
)
763 virtio_snd_ctrl_command
*cmd
;
765 if (unlikely(qatomic_read(&s
->processing_cmdq
))) {
769 WITH_QEMU_LOCK_GUARD(&s
->cmdq_mutex
) {
770 qatomic_set(&s
->processing_cmdq
, true);
771 while (!QTAILQ_EMPTY(&s
->cmdq
)) {
772 cmd
= QTAILQ_FIRST(&s
->cmdq
);
774 /* process command */
777 QTAILQ_REMOVE(&s
->cmdq
, cmd
, next
);
779 virtio_snd_ctrl_cmd_free(cmd
);
781 qatomic_set(&s
->processing_cmdq
, false);
786 * The control message handler. Pops an element from the control virtqueue,
787 * and stores them to VirtIOSound's cmdq queue and finally calls
788 * virtio_snd_process_cmdq() for processing.
790 * @vdev: VirtIOSound device
791 * @vq: Control virtqueue
793 static void virtio_snd_handle_ctrl(VirtIODevice
*vdev
, VirtQueue
*vq
)
795 VirtIOSound
*s
= VIRTIO_SND(vdev
);
796 VirtQueueElement
*elem
;
797 virtio_snd_ctrl_command
*cmd
;
799 trace_virtio_snd_handle_ctrl(vdev
, vq
);
801 if (!virtio_queue_ready(vq
)) {
805 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
807 cmd
= g_new0(virtio_snd_ctrl_command
, 1);
810 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
811 QTAILQ_INSERT_TAIL(&s
->cmdq
, cmd
, next
);
812 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
815 virtio_snd_process_cmdq(s
);
819 * The event virtqueue handler.
820 * Not implemented yet.
822 * @vdev: VirtIOSound device
825 static void virtio_snd_handle_event(VirtIODevice
*vdev
, VirtQueue
*vq
)
827 qemu_log_mask(LOG_UNIMP
, "virtio_snd: event queue is unimplemented.\n");
828 trace_virtio_snd_handle_event();
831 static inline void empty_invalid_queue(VirtIODevice
*vdev
, VirtQueue
*vq
)
833 VirtIOSoundPCMBuffer
*buffer
= NULL
;
834 VirtIOSoundPCMStream
*stream
= NULL
;
835 virtio_snd_pcm_status resp
= { 0 };
836 VirtIOSound
*vsnd
= VIRTIO_SND(vdev
);
839 for (uint32_t i
= 0; i
< vsnd
->snd_conf
.streams
; i
++) {
840 stream
= vsnd
->pcm
->streams
[i
];
843 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
844 while (!QSIMPLEQ_EMPTY(&stream
->invalid
)) {
845 buffer
= QSIMPLEQ_FIRST(&stream
->invalid
);
846 if (buffer
->vq
!= vq
) {
850 resp
.status
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
851 iov_from_buf(buffer
->elem
->in_sg
,
852 buffer
->elem
->in_num
,
855 sizeof(virtio_snd_pcm_status
));
858 sizeof(virtio_snd_pcm_status
));
859 QSIMPLEQ_REMOVE_HEAD(&stream
->invalid
, entry
);
860 virtio_snd_pcm_buffer_free(buffer
);
864 * Notify vq about virtio_snd_pcm_status responses.
865 * Buffer responses must be notified separately later.
867 virtio_notify(vdev
, vq
);
875 * The tx virtqueue handler. Makes the buffers available to their respective
876 * streams for consumption.
878 * @vdev: VirtIOSound device
881 static void virtio_snd_handle_tx_xfer(VirtIODevice
*vdev
, VirtQueue
*vq
)
883 VirtIOSound
*s
= VIRTIO_SND(vdev
);
884 VirtIOSoundPCMStream
*stream
= NULL
;
885 VirtIOSoundPCMBuffer
*buffer
;
886 VirtQueueElement
*elem
;
888 virtio_snd_pcm_xfer hdr
;
891 * If any of the I/O messages are invalid, put them in stream->invalid and
892 * return them after the for loop.
894 bool must_empty_invalid_queue
= false;
896 if (!virtio_queue_ready(vq
)) {
899 trace_virtio_snd_handle_tx_xfer();
902 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
906 /* get the message hdr object */
907 msg_sz
= iov_to_buf(elem
->out_sg
,
911 sizeof(virtio_snd_pcm_xfer
));
912 if (msg_sz
!= sizeof(virtio_snd_pcm_xfer
)) {
915 stream_id
= le32_to_cpu(hdr
.stream_id
);
917 if (stream_id
>= s
->snd_conf
.streams
918 || s
->pcm
->streams
[stream_id
] == NULL
) {
922 stream
= s
->pcm
->streams
[stream_id
];
923 if (stream
->info
.direction
!= VIRTIO_SND_D_OUTPUT
) {
927 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
928 size
= iov_size(elem
->out_sg
, elem
->out_num
) - msg_sz
;
930 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
) + size
);
932 buffer
->populated
= false;
937 QSIMPLEQ_INSERT_TAIL(&stream
->queue
, buffer
, entry
);
942 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
943 must_empty_invalid_queue
= true;
944 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
));
947 QSIMPLEQ_INSERT_TAIL(&stream
->invalid
, buffer
, entry
);
951 if (must_empty_invalid_queue
) {
952 empty_invalid_queue(vdev
, vq
);
957 * The rx virtqueue handler. Makes the buffers available to their respective
958 * streams for consumption.
960 * @vdev: VirtIOSound device
963 static void virtio_snd_handle_rx_xfer(VirtIODevice
*vdev
, VirtQueue
*vq
)
965 VirtIOSound
*s
= VIRTIO_SND(vdev
);
966 VirtIOSoundPCMStream
*stream
= NULL
;
967 VirtIOSoundPCMBuffer
*buffer
;
968 VirtQueueElement
*elem
;
970 virtio_snd_pcm_xfer hdr
;
973 * if any of the I/O messages are invalid, put them in stream->invalid and
974 * return them after the for loop.
976 bool must_empty_invalid_queue
= false;
978 if (!virtio_queue_ready(vq
)) {
981 trace_virtio_snd_handle_rx_xfer();
984 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
988 /* get the message hdr object */
989 msg_sz
= iov_to_buf(elem
->out_sg
,
993 sizeof(virtio_snd_pcm_xfer
));
994 if (msg_sz
!= sizeof(virtio_snd_pcm_xfer
)) {
997 stream_id
= le32_to_cpu(hdr
.stream_id
);
999 if (stream_id
>= s
->snd_conf
.streams
1000 || !s
->pcm
->streams
[stream_id
]) {
1004 stream
= s
->pcm
->streams
[stream_id
];
1005 if (stream
== NULL
|| stream
->info
.direction
!= VIRTIO_SND_D_INPUT
) {
1008 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1009 size
= iov_size(elem
->in_sg
, elem
->in_num
) -
1010 sizeof(virtio_snd_pcm_status
);
1011 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
) + size
);
1012 buffer
->elem
= elem
;
1016 QSIMPLEQ_INSERT_TAIL(&stream
->queue
, buffer
, entry
);
1021 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1022 must_empty_invalid_queue
= true;
1023 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
));
1024 buffer
->elem
= elem
;
1026 QSIMPLEQ_INSERT_TAIL(&stream
->invalid
, buffer
, entry
);
1030 if (must_empty_invalid_queue
) {
1031 empty_invalid_queue(vdev
, vq
);
1035 static uint64_t get_features(VirtIODevice
*vdev
, uint64_t features
,
1039 * virtio-v1.2-csd01, 5.14.3,
1041 * None currently defined.
1043 VirtIOSound
*s
= VIRTIO_SND(vdev
);
1044 features
|= s
->features
;
1046 trace_virtio_snd_get_features(vdev
, features
);
1052 virtio_snd_vm_state_change(void *opaque
, bool running
,
1056 trace_virtio_snd_vm_state_running();
1058 trace_virtio_snd_vm_state_stopped();
1062 static void virtio_snd_realize(DeviceState
*dev
, Error
**errp
)
1065 VirtIOSound
*vsnd
= VIRTIO_SND(dev
);
1066 VirtIODevice
*vdev
= VIRTIO_DEVICE(dev
);
1067 virtio_snd_pcm_set_params default_params
= { 0 };
1070 trace_virtio_snd_realize(vsnd
);
1072 /* check number of jacks and streams */
1073 if (vsnd
->snd_conf
.jacks
> 8) {
1075 "Invalid number of jacks: %"PRIu32
,
1076 vsnd
->snd_conf
.jacks
);
1079 if (vsnd
->snd_conf
.streams
< 1 || vsnd
->snd_conf
.streams
> 10) {
1081 "Invalid number of streams: %"PRIu32
,
1082 vsnd
->snd_conf
.streams
);
1086 if (vsnd
->snd_conf
.chmaps
> VIRTIO_SND_CHMAP_MAX_SIZE
) {
1088 "Invalid number of channel maps: %"PRIu32
,
1089 vsnd
->snd_conf
.chmaps
);
1093 if (!AUD_register_card("virtio-sound", &vsnd
->card
, errp
)) {
1098 qemu_add_vm_change_state_handler(virtio_snd_vm_state_change
, vsnd
);
1100 vsnd
->pcm
= g_new0(VirtIOSoundPCM
, 1);
1101 vsnd
->pcm
->snd
= vsnd
;
1102 vsnd
->pcm
->streams
=
1103 g_new0(VirtIOSoundPCMStream
*, vsnd
->snd_conf
.streams
);
1104 vsnd
->pcm
->pcm_params
=
1105 g_new0(virtio_snd_pcm_set_params
, vsnd
->snd_conf
.streams
);
1107 virtio_init(vdev
, VIRTIO_ID_SOUND
, sizeof(virtio_snd_config
));
1108 virtio_add_feature(&vsnd
->features
, VIRTIO_F_VERSION_1
);
1110 /* set default params for all streams */
1111 default_params
.features
= 0;
1112 default_params
.buffer_bytes
= cpu_to_le32(8192);
1113 default_params
.period_bytes
= cpu_to_le32(2048);
1114 default_params
.channels
= 2;
1115 default_params
.format
= VIRTIO_SND_PCM_FMT_S16
;
1116 default_params
.rate
= VIRTIO_SND_PCM_RATE_48000
;
1117 vsnd
->queues
[VIRTIO_SND_VQ_CONTROL
] =
1118 virtio_add_queue(vdev
, 64, virtio_snd_handle_ctrl
);
1119 vsnd
->queues
[VIRTIO_SND_VQ_EVENT
] =
1120 virtio_add_queue(vdev
, 64, virtio_snd_handle_event
);
1121 vsnd
->queues
[VIRTIO_SND_VQ_TX
] =
1122 virtio_add_queue(vdev
, 64, virtio_snd_handle_tx_xfer
);
1123 vsnd
->queues
[VIRTIO_SND_VQ_RX
] =
1124 virtio_add_queue(vdev
, 64, virtio_snd_handle_rx_xfer
);
1125 qemu_mutex_init(&vsnd
->cmdq_mutex
);
1126 QTAILQ_INIT(&vsnd
->cmdq
);
1128 for (uint32_t i
= 0; i
< vsnd
->snd_conf
.streams
; i
++) {
1129 status
= virtio_snd_set_pcm_params(vsnd
, i
, &default_params
);
1130 if (status
!= cpu_to_le32(VIRTIO_SND_S_OK
)) {
1132 "Can't initialize stream params, device responded with %s.",
1133 print_code(status
));
1136 status
= virtio_snd_pcm_prepare(vsnd
, i
);
1137 if (status
!= cpu_to_le32(VIRTIO_SND_S_OK
)) {
1139 "Can't prepare streams, device responded with %s.",
1140 print_code(status
));
1148 virtio_snd_unrealize(dev
);
1151 static inline void return_tx_buffer(VirtIOSoundPCMStream
*stream
,
1152 VirtIOSoundPCMBuffer
*buffer
)
1154 virtio_snd_pcm_status resp
= { 0 };
1155 resp
.status
= cpu_to_le32(VIRTIO_SND_S_OK
);
1156 resp
.latency_bytes
= cpu_to_le32((uint32_t)buffer
->size
);
1157 iov_from_buf(buffer
->elem
->in_sg
,
1158 buffer
->elem
->in_num
,
1161 sizeof(virtio_snd_pcm_status
));
1162 virtqueue_push(buffer
->vq
,
1164 sizeof(virtio_snd_pcm_status
));
1165 virtio_notify(VIRTIO_DEVICE(stream
->s
), buffer
->vq
);
1166 QSIMPLEQ_REMOVE(&stream
->queue
,
1168 VirtIOSoundPCMBuffer
,
1170 virtio_snd_pcm_buffer_free(buffer
);
1174 * AUD_* output callback.
1176 * @data: VirtIOSoundPCMStream stream
1177 * @available: number of bytes that can be written with AUD_write()
1179 static void virtio_snd_pcm_out_cb(void *data
, int available
)
1181 VirtIOSoundPCMStream
*stream
= data
;
1182 VirtIOSoundPCMBuffer
*buffer
;
1185 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1186 while (!QSIMPLEQ_EMPTY(&stream
->queue
)) {
1187 buffer
= QSIMPLEQ_FIRST(&stream
->queue
);
1188 if (!virtio_queue_ready(buffer
->vq
)) {
1191 if (!stream
->active
) {
1192 /* Stream has stopped, so do not perform AUD_write. */
1193 return_tx_buffer(stream
, buffer
);
1196 if (!buffer
->populated
) {
1197 iov_to_buf(buffer
->elem
->out_sg
,
1198 buffer
->elem
->out_num
,
1199 sizeof(virtio_snd_pcm_xfer
),
1202 buffer
->populated
= true;
1205 size
= AUD_write(stream
->voice
.out
,
1206 buffer
->data
+ buffer
->offset
,
1207 MIN(buffer
->size
, available
));
1208 assert(size
<= MIN(buffer
->size
, available
));
1210 /* break out of both loops */
1214 buffer
->size
-= size
;
1215 buffer
->offset
+= size
;
1217 if (buffer
->size
< 1) {
1218 return_tx_buffer(stream
, buffer
);
1233 * Flush all buffer data from this input stream's queue into the driver's
1236 * @stream: VirtIOSoundPCMStream *stream
1238 static inline void return_rx_buffer(VirtIOSoundPCMStream
*stream
,
1239 VirtIOSoundPCMBuffer
*buffer
)
1241 virtio_snd_pcm_status resp
= { 0 };
1242 resp
.status
= cpu_to_le32(VIRTIO_SND_S_OK
);
1243 resp
.latency_bytes
= 0;
1244 /* Copy data -if any- to guest */
1245 iov_from_buf(buffer
->elem
->in_sg
,
1246 buffer
->elem
->in_num
,
1250 iov_from_buf(buffer
->elem
->in_sg
,
1251 buffer
->elem
->in_num
,
1254 sizeof(virtio_snd_pcm_status
));
1255 virtqueue_push(buffer
->vq
,
1257 sizeof(virtio_snd_pcm_status
) + buffer
->size
);
1258 virtio_notify(VIRTIO_DEVICE(stream
->s
), buffer
->vq
);
1259 QSIMPLEQ_REMOVE(&stream
->queue
,
1261 VirtIOSoundPCMBuffer
,
1263 virtio_snd_pcm_buffer_free(buffer
);
1268 * AUD_* input callback.
1270 * @data: VirtIOSoundPCMStream stream
1271 * @available: number of bytes that can be read with AUD_read()
1273 static void virtio_snd_pcm_in_cb(void *data
, int available
)
1275 VirtIOSoundPCMStream
*stream
= data
;
1276 VirtIOSoundPCMBuffer
*buffer
;
1279 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1280 while (!QSIMPLEQ_EMPTY(&stream
->queue
)) {
1281 buffer
= QSIMPLEQ_FIRST(&stream
->queue
);
1282 if (!virtio_queue_ready(buffer
->vq
)) {
1285 if (!stream
->active
) {
1286 /* Stream has stopped, so do not perform AUD_read. */
1287 return_rx_buffer(stream
, buffer
);
1292 size
= AUD_read(stream
->voice
.in
,
1293 buffer
->data
+ buffer
->size
,
1294 MIN(available
, (stream
->params
.period_bytes
-
1300 buffer
->size
+= size
;
1302 if (buffer
->size
>= stream
->params
.period_bytes
) {
1303 return_rx_buffer(stream
, buffer
);
1318 * Flush all buffer data from this output stream's queue into the driver's
1321 * @stream: VirtIOSoundPCMStream *stream
1323 static inline void virtio_snd_pcm_flush(VirtIOSoundPCMStream
*stream
)
1325 VirtIOSoundPCMBuffer
*buffer
;
1326 void (*cb
)(VirtIOSoundPCMStream
*, VirtIOSoundPCMBuffer
*) =
1327 (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) ? return_tx_buffer
:
1330 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1331 while (!QSIMPLEQ_EMPTY(&stream
->queue
)) {
1332 buffer
= QSIMPLEQ_FIRST(&stream
->queue
);
1338 static void virtio_snd_unrealize(DeviceState
*dev
)
1340 VirtIODevice
*vdev
= VIRTIO_DEVICE(dev
);
1341 VirtIOSound
*vsnd
= VIRTIO_SND(dev
);
1342 VirtIOSoundPCMStream
*stream
;
1344 qemu_del_vm_change_state_handler(vsnd
->vmstate
);
1345 trace_virtio_snd_unrealize(vsnd
);
1348 if (vsnd
->pcm
->streams
) {
1349 for (uint32_t i
= 0; i
< vsnd
->snd_conf
.streams
; i
++) {
1350 stream
= vsnd
->pcm
->streams
[i
];
1352 virtio_snd_process_cmdq(stream
->s
);
1353 virtio_snd_pcm_close(stream
);
1354 qemu_mutex_destroy(&stream
->queue_mutex
);
1358 g_free(vsnd
->pcm
->streams
);
1360 g_free(vsnd
->pcm
->pcm_params
);
1364 AUD_remove_card(&vsnd
->card
);
1365 qemu_mutex_destroy(&vsnd
->cmdq_mutex
);
1366 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_CONTROL
]);
1367 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_EVENT
]);
1368 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_TX
]);
1369 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_RX
]);
1370 virtio_cleanup(vdev
);
1374 static void virtio_snd_reset(VirtIODevice
*vdev
)
1376 VirtIOSound
*s
= VIRTIO_SND(vdev
);
1377 virtio_snd_ctrl_command
*cmd
;
1379 WITH_QEMU_LOCK_GUARD(&s
->cmdq_mutex
) {
1380 while (!QTAILQ_EMPTY(&s
->cmdq
)) {
1381 cmd
= QTAILQ_FIRST(&s
->cmdq
);
1382 QTAILQ_REMOVE(&s
->cmdq
, cmd
, next
);
1383 virtio_snd_ctrl_cmd_free(cmd
);
1388 static void virtio_snd_class_init(ObjectClass
*klass
, void *data
)
1390 DeviceClass
*dc
= DEVICE_CLASS(klass
);
1391 VirtioDeviceClass
*vdc
= VIRTIO_DEVICE_CLASS(klass
);
1394 set_bit(DEVICE_CATEGORY_SOUND
, dc
->categories
);
1395 device_class_set_props(dc
, virtio_snd_properties
);
1397 dc
->vmsd
= &vmstate_virtio_snd
;
1398 vdc
->vmsd
= &vmstate_virtio_snd_device
;
1399 vdc
->realize
= virtio_snd_realize
;
1400 vdc
->unrealize
= virtio_snd_unrealize
;
1401 vdc
->get_config
= virtio_snd_get_config
;
1402 vdc
->set_config
= virtio_snd_set_config
;
1403 vdc
->get_features
= get_features
;
1404 vdc
->reset
= virtio_snd_reset
;
1405 vdc
->legacy_features
= 0;
1408 static const TypeInfo virtio_snd_types
[] = {
1410 .name
= TYPE_VIRTIO_SND
,
1411 .parent
= TYPE_VIRTIO_DEVICE
,
1412 .instance_size
= sizeof(VirtIOSound
),
1413 .class_init
= virtio_snd_class_init
,
1417 DEFINE_TYPES(virtio_snd_types
)