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
);
40 static uint32_t supported_formats
= BIT(VIRTIO_SND_PCM_FMT_S8
)
41 | BIT(VIRTIO_SND_PCM_FMT_U8
)
42 | BIT(VIRTIO_SND_PCM_FMT_S16
)
43 | BIT(VIRTIO_SND_PCM_FMT_U16
)
44 | BIT(VIRTIO_SND_PCM_FMT_S32
)
45 | BIT(VIRTIO_SND_PCM_FMT_U32
)
46 | BIT(VIRTIO_SND_PCM_FMT_FLOAT
);
48 static uint32_t supported_rates
= BIT(VIRTIO_SND_PCM_RATE_5512
)
49 | BIT(VIRTIO_SND_PCM_RATE_8000
)
50 | BIT(VIRTIO_SND_PCM_RATE_11025
)
51 | BIT(VIRTIO_SND_PCM_RATE_16000
)
52 | BIT(VIRTIO_SND_PCM_RATE_22050
)
53 | BIT(VIRTIO_SND_PCM_RATE_32000
)
54 | BIT(VIRTIO_SND_PCM_RATE_44100
)
55 | BIT(VIRTIO_SND_PCM_RATE_48000
)
56 | BIT(VIRTIO_SND_PCM_RATE_64000
)
57 | BIT(VIRTIO_SND_PCM_RATE_88200
)
58 | BIT(VIRTIO_SND_PCM_RATE_96000
)
59 | BIT(VIRTIO_SND_PCM_RATE_176400
)
60 | BIT(VIRTIO_SND_PCM_RATE_192000
)
61 | BIT(VIRTIO_SND_PCM_RATE_384000
);
63 static const VMStateDescription vmstate_virtio_snd_device
= {
64 .name
= TYPE_VIRTIO_SND
,
65 .version_id
= VIRTIO_SOUND_VM_VERSION
,
66 .minimum_version_id
= VIRTIO_SOUND_VM_VERSION
,
69 static const VMStateDescription vmstate_virtio_snd
= {
70 .name
= TYPE_VIRTIO_SND
,
71 .minimum_version_id
= VIRTIO_SOUND_VM_VERSION
,
72 .version_id
= VIRTIO_SOUND_VM_VERSION
,
73 .fields
= (VMStateField
[]) {
74 VMSTATE_VIRTIO_DEVICE
,
79 static Property virtio_snd_properties
[] = {
80 DEFINE_AUDIO_PROPERTIES(VirtIOSound
, card
),
81 DEFINE_PROP_UINT32("jacks", VirtIOSound
, snd_conf
.jacks
,
82 VIRTIO_SOUND_JACK_DEFAULT
),
83 DEFINE_PROP_UINT32("streams", VirtIOSound
, snd_conf
.streams
,
84 VIRTIO_SOUND_STREAM_DEFAULT
),
85 DEFINE_PROP_UINT32("chmaps", VirtIOSound
, snd_conf
.chmaps
,
86 VIRTIO_SOUND_CHMAP_DEFAULT
),
87 DEFINE_PROP_END_OF_LIST(),
91 virtio_snd_get_config(VirtIODevice
*vdev
, uint8_t *config
)
93 VirtIOSound
*s
= VIRTIO_SND(vdev
);
94 virtio_snd_config
*sndconfig
=
95 (virtio_snd_config
*)config
;
96 trace_virtio_snd_get_config(vdev
,
101 memcpy(sndconfig
, &s
->snd_conf
, sizeof(s
->snd_conf
));
102 cpu_to_le32s(&sndconfig
->jacks
);
103 cpu_to_le32s(&sndconfig
->streams
);
104 cpu_to_le32s(&sndconfig
->chmaps
);
109 virtio_snd_set_config(VirtIODevice
*vdev
, const uint8_t *config
)
111 VirtIOSound
*s
= VIRTIO_SND(vdev
);
112 const virtio_snd_config
*sndconfig
=
113 (const virtio_snd_config
*)config
;
116 trace_virtio_snd_set_config(vdev
,
124 memcpy(&s
->snd_conf
, sndconfig
, sizeof(virtio_snd_config
));
125 le32_to_cpus(&s
->snd_conf
.jacks
);
126 le32_to_cpus(&s
->snd_conf
.streams
);
127 le32_to_cpus(&s
->snd_conf
.chmaps
);
132 virtio_snd_pcm_buffer_free(VirtIOSoundPCMBuffer
*buffer
)
134 g_free(buffer
->elem
);
139 virtio_snd_ctrl_cmd_free(virtio_snd_ctrl_command
*cmd
)
146 * Get a specific stream from the virtio sound card device.
147 * Returns NULL if @stream_id is invalid or not allocated.
149 * @s: VirtIOSound device
150 * @stream_id: stream id
152 static VirtIOSoundPCMStream
*virtio_snd_pcm_get_stream(VirtIOSound
*s
,
155 return stream_id
>= s
->snd_conf
.streams
? NULL
:
156 s
->pcm
->streams
[stream_id
];
160 * Get params for a specific stream.
162 * @s: VirtIOSound device
163 * @stream_id: stream id
165 static virtio_snd_pcm_set_params
*virtio_snd_pcm_get_params(VirtIOSound
*s
,
168 return stream_id
>= s
->snd_conf
.streams
? NULL
169 : &s
->pcm
->pcm_params
[stream_id
];
173 * Handle the VIRTIO_SND_R_PCM_INFO request.
174 * The function writes the info structs to the request element.
176 * @s: VirtIOSound device
177 * @cmd: The request command queue element from VirtIOSound cmdq field
179 static void virtio_snd_handle_pcm_info(VirtIOSound
*s
,
180 virtio_snd_ctrl_command
*cmd
)
182 uint32_t stream_id
, start_id
, count
, size
;
183 virtio_snd_pcm_info val
;
184 virtio_snd_query_info req
;
185 VirtIOSoundPCMStream
*stream
= NULL
;
186 g_autofree virtio_snd_pcm_info
*pcm_info
= NULL
;
187 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
191 sizeof(virtio_snd_query_info
));
193 if (msg_sz
!= sizeof(virtio_snd_query_info
)) {
195 * TODO: do we need to set DEVICE_NEEDS_RESET?
197 qemu_log_mask(LOG_GUEST_ERROR
,
198 "%s: virtio-snd command size incorrect %zu vs \
199 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_query_info
));
200 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
204 start_id
= le32_to_cpu(req
.start_id
);
205 count
= le32_to_cpu(req
.count
);
206 size
= le32_to_cpu(req
.size
);
208 if (iov_size(cmd
->elem
->in_sg
, cmd
->elem
->in_num
) <
209 sizeof(virtio_snd_hdr
) + size
* count
) {
211 * TODO: do we need to set DEVICE_NEEDS_RESET?
213 error_report("pcm info: buffer too small, got: %zu, needed: %zu",
214 iov_size(cmd
->elem
->in_sg
, cmd
->elem
->in_num
),
215 sizeof(virtio_snd_pcm_info
));
216 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
220 pcm_info
= g_new0(virtio_snd_pcm_info
, count
);
221 for (uint32_t i
= 0; i
< count
; i
++) {
222 stream_id
= i
+ start_id
;
223 trace_virtio_snd_handle_pcm_info(stream_id
);
224 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
226 error_report("Invalid stream id: %"PRIu32
, stream_id
);
227 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
231 val
.hdr
.hda_fn_nid
= cpu_to_le32(val
.hdr
.hda_fn_nid
);
232 val
.features
= cpu_to_le32(val
.features
);
233 val
.formats
= cpu_to_le64(val
.formats
);
234 val
.rates
= cpu_to_le64(val
.rates
);
236 * 5.14.6.6.2.1 Device Requirements: Stream Information The device MUST
237 * NOT set undefined feature, format, rate and direction values. The
238 * device MUST initialize the padding bytes to 0.
241 memset(&pcm_info
[i
].padding
, 0, 5);
244 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
245 iov_from_buf(cmd
->elem
->in_sg
,
247 sizeof(virtio_snd_hdr
),
249 sizeof(virtio_snd_pcm_info
) * count
);
253 * Set the given stream params.
254 * Called by both virtio_snd_handle_pcm_set_params and during device
256 * Returns the response status code. (VIRTIO_SND_S_*).
258 * @s: VirtIOSound device
259 * @params: The PCM params as defined in the virtio specification
262 uint32_t virtio_snd_set_pcm_params(VirtIOSound
*s
,
264 virtio_snd_pcm_set_params
*params
)
266 virtio_snd_pcm_set_params
*st_params
;
268 if (stream_id
>= s
->snd_conf
.streams
|| s
->pcm
->pcm_params
== NULL
) {
270 * TODO: do we need to set DEVICE_NEEDS_RESET?
272 virtio_error(VIRTIO_DEVICE(s
), "Streams have not been initialized.\n");
273 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
276 st_params
= virtio_snd_pcm_get_params(s
, stream_id
);
278 if (params
->channels
< 1 || params
->channels
> AUDIO_MAX_CHANNELS
) {
279 error_report("Number of channels is not supported.");
280 return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
282 if (!(supported_formats
& BIT(params
->format
))) {
283 error_report("Stream format is not supported.");
284 return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
286 if (!(supported_rates
& BIT(params
->rate
))) {
287 error_report("Stream rate is not supported.");
288 return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
291 st_params
->buffer_bytes
= le32_to_cpu(params
->buffer_bytes
);
292 st_params
->period_bytes
= le32_to_cpu(params
->period_bytes
);
293 st_params
->features
= le32_to_cpu(params
->features
);
294 /* the following are uint8_t, so there's no need to bswap the values. */
295 st_params
->channels
= params
->channels
;
296 st_params
->format
= params
->format
;
297 st_params
->rate
= params
->rate
;
299 return cpu_to_le32(VIRTIO_SND_S_OK
);
303 * Handles the VIRTIO_SND_R_PCM_SET_PARAMS request.
305 * @s: VirtIOSound device
306 * @cmd: The request command queue element from VirtIOSound cmdq field
308 static void virtio_snd_handle_pcm_set_params(VirtIOSound
*s
,
309 virtio_snd_ctrl_command
*cmd
)
311 virtio_snd_pcm_set_params req
= { 0 };
313 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
317 sizeof(virtio_snd_pcm_set_params
));
319 if (msg_sz
!= sizeof(virtio_snd_pcm_set_params
)) {
321 * TODO: do we need to set DEVICE_NEEDS_RESET?
323 qemu_log_mask(LOG_GUEST_ERROR
,
324 "%s: virtio-snd command size incorrect %zu vs \
325 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_pcm_set_params
));
326 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
329 stream_id
= le32_to_cpu(req
.hdr
.stream_id
);
330 trace_virtio_snd_handle_pcm_set_params(stream_id
);
331 cmd
->resp
.code
= virtio_snd_set_pcm_params(s
, stream_id
, &req
);
335 * Get a QEMU Audiosystem compatible format value from a VIRTIO_SND_PCM_FMT_*
337 static AudioFormat
virtio_snd_get_qemu_format(uint32_t format
)
340 case VIRTIO_SND_PCM_FMT_##FMT: \
341 return AUDIO_FORMAT_##FMT;
350 case VIRTIO_SND_PCM_FMT_FLOAT
:
351 return AUDIO_FORMAT_F32
;
353 g_assert_not_reached();
360 * Get a QEMU Audiosystem compatible frequency value from a
361 * VIRTIO_SND_PCM_RATE_*
363 static uint32_t virtio_snd_get_qemu_freq(uint32_t rate
)
366 case VIRTIO_SND_PCM_RATE_##RATE: \
385 g_assert_not_reached();
392 * Get QEMU Audiosystem compatible audsettings from virtio based pcm stream
395 static void virtio_snd_get_qemu_audsettings(audsettings
*as
,
396 virtio_snd_pcm_set_params
*params
)
398 as
->nchannels
= MIN(AUDIO_MAX_CHANNELS
, params
->channels
);
399 as
->fmt
= virtio_snd_get_qemu_format(params
->format
);
400 as
->freq
= virtio_snd_get_qemu_freq(params
->rate
);
401 as
->endianness
= target_words_bigendian() ? 1 : 0;
405 * Close a stream and free all its resources.
407 * @stream: VirtIOSoundPCMStream *stream
409 static void virtio_snd_pcm_close(VirtIOSoundPCMStream
*stream
)
412 virtio_snd_pcm_flush(stream
);
413 if (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) {
414 AUD_close_out(&stream
->pcm
->snd
->card
, stream
->voice
.out
);
415 stream
->voice
.out
= NULL
;
416 } else if (stream
->info
.direction
== VIRTIO_SND_D_INPUT
) {
417 AUD_close_in(&stream
->pcm
->snd
->card
, stream
->voice
.in
);
418 stream
->voice
.in
= NULL
;
424 * Prepares a VirtIOSound card stream.
425 * Returns the response status code. (VIRTIO_SND_S_*).
427 * @s: VirtIOSound device
428 * @stream_id: stream id
430 static uint32_t virtio_snd_pcm_prepare(VirtIOSound
*s
, uint32_t stream_id
)
433 virtio_snd_pcm_set_params
*params
;
434 VirtIOSoundPCMStream
*stream
;
436 if (s
->pcm
->streams
== NULL
||
437 s
->pcm
->pcm_params
== NULL
||
438 stream_id
>= s
->snd_conf
.streams
) {
439 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
442 params
= virtio_snd_pcm_get_params(s
, stream_id
);
443 if (params
== NULL
) {
444 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
447 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
448 if (stream
== NULL
) {
449 stream
= g_new0(VirtIOSoundPCMStream
, 1);
450 stream
->active
= false;
451 stream
->id
= stream_id
;
452 stream
->pcm
= s
->pcm
;
454 qemu_mutex_init(&stream
->queue_mutex
);
455 QSIMPLEQ_INIT(&stream
->queue
);
456 QSIMPLEQ_INIT(&stream
->invalid
);
459 * stream_id >= s->snd_conf.streams was checked before so this is
462 s
->pcm
->streams
[stream_id
] = stream
;
465 virtio_snd_get_qemu_audsettings(&as
, params
);
466 stream
->info
.direction
= stream_id
< s
->snd_conf
.streams
/ 2 +
467 (s
->snd_conf
.streams
& 1) ? VIRTIO_SND_D_OUTPUT
: VIRTIO_SND_D_INPUT
;
468 stream
->info
.hdr
.hda_fn_nid
= VIRTIO_SOUND_HDA_FN_NID
;
469 stream
->info
.features
= 0;
470 stream
->info
.channels_min
= 1;
471 stream
->info
.channels_max
= as
.nchannels
;
472 stream
->info
.formats
= supported_formats
;
473 stream
->info
.rates
= supported_rates
;
474 stream
->params
= *params
;
476 stream
->positions
[0] = VIRTIO_SND_CHMAP_FL
;
477 stream
->positions
[1] = VIRTIO_SND_CHMAP_FR
;
480 if (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) {
481 stream
->voice
.out
= AUD_open_out(&s
->card
,
485 virtio_snd_pcm_out_cb
,
487 AUD_set_volume_out(stream
->voice
.out
, 0, 255, 255);
489 stream
->voice
.in
= AUD_open_in(&s
->card
,
493 virtio_snd_pcm_in_cb
,
495 AUD_set_volume_in(stream
->voice
.in
, 0, 255, 255);
498 return cpu_to_le32(VIRTIO_SND_S_OK
);
501 static const char *print_code(uint32_t code
)
504 case VIRTIO_SND_R_##CODE: \
505 return "VIRTIO_SND_R_"#CODE
511 CASE(PCM_SET_PARAMS
);
518 return "invalid code";
525 * Handles VIRTIO_SND_R_PCM_PREPARE.
527 * @s: VirtIOSound device
528 * @cmd: The request command queue element from VirtIOSound cmdq field
530 static void virtio_snd_handle_pcm_prepare(VirtIOSound
*s
,
531 virtio_snd_ctrl_command
*cmd
)
534 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
536 sizeof(virtio_snd_hdr
),
540 stream_id
= le32_to_cpu(stream_id
);
541 cmd
->resp
.code
= msg_sz
== sizeof(stream_id
)
542 ? virtio_snd_pcm_prepare(s
, stream_id
)
543 : cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
547 * Handles VIRTIO_SND_R_PCM_START.
549 * @s: VirtIOSound device
550 * @cmd: The request command queue element from VirtIOSound cmdq field
551 * @start: whether to start or stop the device
553 static void virtio_snd_handle_pcm_start_stop(VirtIOSound
*s
,
554 virtio_snd_ctrl_command
*cmd
,
557 VirtIOSoundPCMStream
*stream
;
558 virtio_snd_pcm_hdr req
;
560 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
564 sizeof(virtio_snd_pcm_hdr
));
566 if (msg_sz
!= sizeof(virtio_snd_pcm_hdr
)) {
567 qemu_log_mask(LOG_GUEST_ERROR
,
568 "%s: virtio-snd command size incorrect %zu vs \
569 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_pcm_hdr
));
570 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
574 stream_id
= le32_to_cpu(req
.stream_id
);
575 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
576 trace_virtio_snd_handle_pcm_start_stop(start
? "VIRTIO_SND_R_PCM_START" :
577 "VIRTIO_SND_R_PCM_STOP", stream_id
);
579 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
581 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
582 stream
->active
= start
;
584 if (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) {
585 AUD_set_active_out(stream
->voice
.out
, start
);
587 AUD_set_active_in(stream
->voice
.in
, start
);
590 error_report("Invalid stream id: %"PRIu32
, stream_id
);
591 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
594 stream
->active
= start
;
598 * Returns the number of I/O messages that are being processed.
600 * @stream: VirtIOSoundPCMStream
602 static size_t virtio_snd_pcm_get_io_msgs_count(VirtIOSoundPCMStream
*stream
)
604 VirtIOSoundPCMBuffer
*buffer
, *next
;
607 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
608 QSIMPLEQ_FOREACH_SAFE(buffer
, &stream
->queue
, entry
, next
) {
611 QSIMPLEQ_FOREACH_SAFE(buffer
, &stream
->invalid
, entry
, next
) {
619 * Handles VIRTIO_SND_R_PCM_RELEASE.
621 * @s: VirtIOSound device
622 * @cmd: The request command queue element from VirtIOSound cmdq field
624 static void virtio_snd_handle_pcm_release(VirtIOSound
*s
,
625 virtio_snd_ctrl_command
*cmd
)
628 VirtIOSoundPCMStream
*stream
;
629 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
631 sizeof(virtio_snd_hdr
),
635 if (msg_sz
!= sizeof(stream_id
)) {
637 * TODO: do we need to set DEVICE_NEEDS_RESET?
639 qemu_log_mask(LOG_GUEST_ERROR
,
640 "%s: virtio-snd command size incorrect %zu vs \
641 %zu\n", __func__
, msg_sz
, sizeof(stream_id
));
642 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
646 stream_id
= le32_to_cpu(stream_id
);
647 trace_virtio_snd_handle_pcm_release(stream_id
);
648 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
649 if (stream
== NULL
) {
651 * TODO: do we need to set DEVICE_NEEDS_RESET?
653 error_report("already released stream %"PRIu32
, stream_id
);
654 virtio_error(VIRTIO_DEVICE(s
),
655 "already released stream %"PRIu32
,
657 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
661 if (virtio_snd_pcm_get_io_msgs_count(stream
)) {
663 * virtio-v1.2-csd01, 5.14.6.6.5.1,
664 * Device Requirements: Stream Release
666 * - The device MUST complete all pending I/O messages for the
667 * specified stream ID.
668 * - The device MUST NOT complete the control request while there
669 * are pending I/O messages for the specified stream ID.
671 trace_virtio_snd_pcm_stream_flush(stream_id
);
672 virtio_snd_pcm_flush(stream
);
675 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
679 * The actual processing done in virtio_snd_process_cmdq().
681 * @s: VirtIOSound device
682 * @cmd: control command request
685 process_cmd(VirtIOSound
*s
, virtio_snd_ctrl_command
*cmd
)
688 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
692 sizeof(virtio_snd_hdr
));
694 if (msg_sz
!= sizeof(virtio_snd_hdr
)) {
696 * TODO: do we need to set DEVICE_NEEDS_RESET?
698 qemu_log_mask(LOG_GUEST_ERROR
,
699 "%s: virtio-snd command size incorrect %zu vs \
700 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_hdr
));
704 code
= le32_to_cpu(cmd
->ctrl
.code
);
706 trace_virtio_snd_handle_code(code
, print_code(code
));
709 case VIRTIO_SND_R_JACK_INFO
:
710 case VIRTIO_SND_R_JACK_REMAP
:
711 qemu_log_mask(LOG_UNIMP
,
712 "virtio_snd: jack functionality is unimplemented.\n");
713 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
715 case VIRTIO_SND_R_PCM_INFO
:
716 virtio_snd_handle_pcm_info(s
, cmd
);
718 case VIRTIO_SND_R_PCM_START
:
719 virtio_snd_handle_pcm_start_stop(s
, cmd
, true);
721 case VIRTIO_SND_R_PCM_STOP
:
722 virtio_snd_handle_pcm_start_stop(s
, cmd
, false);
724 case VIRTIO_SND_R_PCM_SET_PARAMS
:
725 virtio_snd_handle_pcm_set_params(s
, cmd
);
727 case VIRTIO_SND_R_PCM_PREPARE
:
728 virtio_snd_handle_pcm_prepare(s
, cmd
);
730 case VIRTIO_SND_R_PCM_RELEASE
:
731 virtio_snd_handle_pcm_release(s
, cmd
);
733 case VIRTIO_SND_R_CHMAP_INFO
:
734 qemu_log_mask(LOG_UNIMP
,
735 "virtio_snd: chmap info functionality is unimplemented.\n");
736 trace_virtio_snd_handle_chmap_info();
737 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
741 error_report("virtio snd header not recognized: %"PRIu32
, code
);
742 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
745 iov_from_buf(cmd
->elem
->in_sg
,
749 sizeof(virtio_snd_hdr
));
750 virtqueue_push(cmd
->vq
, cmd
->elem
, sizeof(virtio_snd_hdr
));
751 virtio_notify(VIRTIO_DEVICE(s
), cmd
->vq
);
755 * Consume all elements in command queue.
757 * @s: VirtIOSound device
759 static void virtio_snd_process_cmdq(VirtIOSound
*s
)
761 virtio_snd_ctrl_command
*cmd
;
763 if (unlikely(qatomic_read(&s
->processing_cmdq
))) {
767 WITH_QEMU_LOCK_GUARD(&s
->cmdq_mutex
) {
768 qatomic_set(&s
->processing_cmdq
, true);
769 while (!QTAILQ_EMPTY(&s
->cmdq
)) {
770 cmd
= QTAILQ_FIRST(&s
->cmdq
);
772 /* process command */
775 QTAILQ_REMOVE(&s
->cmdq
, cmd
, next
);
777 virtio_snd_ctrl_cmd_free(cmd
);
779 qatomic_set(&s
->processing_cmdq
, false);
784 * The control message handler. Pops an element from the control virtqueue,
785 * and stores them to VirtIOSound's cmdq queue and finally calls
786 * virtio_snd_process_cmdq() for processing.
788 * @vdev: VirtIOSound device
789 * @vq: Control virtqueue
791 static void virtio_snd_handle_ctrl(VirtIODevice
*vdev
, VirtQueue
*vq
)
793 VirtIOSound
*s
= VIRTIO_SND(vdev
);
794 VirtQueueElement
*elem
;
795 virtio_snd_ctrl_command
*cmd
;
797 trace_virtio_snd_handle_ctrl(vdev
, vq
);
799 if (!virtio_queue_ready(vq
)) {
803 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
805 cmd
= g_new0(virtio_snd_ctrl_command
, 1);
808 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
809 QTAILQ_INSERT_TAIL(&s
->cmdq
, cmd
, next
);
810 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
813 virtio_snd_process_cmdq(s
);
817 * The event virtqueue handler.
818 * Not implemented yet.
820 * @vdev: VirtIOSound device
823 static void virtio_snd_handle_event(VirtIODevice
*vdev
, VirtQueue
*vq
)
825 qemu_log_mask(LOG_UNIMP
, "virtio_snd: event queue is unimplemented.\n");
826 trace_virtio_snd_handle_event();
829 static inline void empty_invalid_queue(VirtIODevice
*vdev
, VirtQueue
*vq
)
831 VirtIOSoundPCMBuffer
*buffer
= NULL
;
832 VirtIOSoundPCMStream
*stream
= NULL
;
833 virtio_snd_pcm_status resp
= { 0 };
834 VirtIOSound
*vsnd
= VIRTIO_SND(vdev
);
837 for (uint32_t i
= 0; i
< vsnd
->snd_conf
.streams
; i
++) {
838 stream
= vsnd
->pcm
->streams
[i
];
841 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
842 while (!QSIMPLEQ_EMPTY(&stream
->invalid
)) {
843 buffer
= QSIMPLEQ_FIRST(&stream
->invalid
);
844 if (buffer
->vq
!= vq
) {
848 resp
.status
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
849 iov_from_buf(buffer
->elem
->in_sg
,
850 buffer
->elem
->in_num
,
853 sizeof(virtio_snd_pcm_status
));
856 sizeof(virtio_snd_pcm_status
));
857 QSIMPLEQ_REMOVE_HEAD(&stream
->invalid
, entry
);
858 virtio_snd_pcm_buffer_free(buffer
);
862 * Notify vq about virtio_snd_pcm_status responses.
863 * Buffer responses must be notified separately later.
865 virtio_notify(vdev
, vq
);
873 * The tx virtqueue handler. Makes the buffers available to their respective
874 * streams for consumption.
876 * @vdev: VirtIOSound device
879 static void virtio_snd_handle_tx_xfer(VirtIODevice
*vdev
, VirtQueue
*vq
)
881 VirtIOSound
*s
= VIRTIO_SND(vdev
);
882 VirtIOSoundPCMStream
*stream
= NULL
;
883 VirtIOSoundPCMBuffer
*buffer
;
884 VirtQueueElement
*elem
;
886 virtio_snd_pcm_xfer hdr
;
889 * If any of the I/O messages are invalid, put them in stream->invalid and
890 * return them after the for loop.
892 bool must_empty_invalid_queue
= false;
894 if (!virtio_queue_ready(vq
)) {
897 trace_virtio_snd_handle_tx_xfer();
900 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
904 /* get the message hdr object */
905 msg_sz
= iov_to_buf(elem
->out_sg
,
909 sizeof(virtio_snd_pcm_xfer
));
910 if (msg_sz
!= sizeof(virtio_snd_pcm_xfer
)) {
913 stream_id
= le32_to_cpu(hdr
.stream_id
);
915 if (stream_id
>= s
->snd_conf
.streams
916 || s
->pcm
->streams
[stream_id
] == NULL
) {
920 stream
= s
->pcm
->streams
[stream_id
];
921 if (stream
->info
.direction
!= VIRTIO_SND_D_OUTPUT
) {
925 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
926 size
= iov_size(elem
->out_sg
, elem
->out_num
) - msg_sz
;
928 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
) + size
);
930 buffer
->populated
= false;
935 QSIMPLEQ_INSERT_TAIL(&stream
->queue
, buffer
, entry
);
940 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
941 must_empty_invalid_queue
= true;
942 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
));
945 QSIMPLEQ_INSERT_TAIL(&stream
->invalid
, buffer
, entry
);
949 if (must_empty_invalid_queue
) {
950 empty_invalid_queue(vdev
, vq
);
955 * The rx virtqueue handler. Makes the buffers available to their respective
956 * streams for consumption.
958 * @vdev: VirtIOSound device
961 static void virtio_snd_handle_rx_xfer(VirtIODevice
*vdev
, VirtQueue
*vq
)
963 VirtIOSound
*s
= VIRTIO_SND(vdev
);
964 VirtIOSoundPCMStream
*stream
= NULL
;
965 VirtIOSoundPCMBuffer
*buffer
;
966 VirtQueueElement
*elem
;
968 virtio_snd_pcm_xfer hdr
;
971 * if any of the I/O messages are invalid, put them in stream->invalid and
972 * return them after the for loop.
974 bool must_empty_invalid_queue
= false;
976 if (!virtio_queue_ready(vq
)) {
979 trace_virtio_snd_handle_rx_xfer();
982 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
986 /* get the message hdr object */
987 msg_sz
= iov_to_buf(elem
->out_sg
,
991 sizeof(virtio_snd_pcm_xfer
));
992 if (msg_sz
!= sizeof(virtio_snd_pcm_xfer
)) {
995 stream_id
= le32_to_cpu(hdr
.stream_id
);
997 if (stream_id
>= s
->snd_conf
.streams
998 || !s
->pcm
->streams
[stream_id
]) {
1002 stream
= s
->pcm
->streams
[stream_id
];
1003 if (stream
== NULL
|| stream
->info
.direction
!= VIRTIO_SND_D_INPUT
) {
1006 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1007 size
= iov_size(elem
->in_sg
, elem
->in_num
) -
1008 sizeof(virtio_snd_pcm_status
);
1009 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
) + size
);
1010 buffer
->elem
= elem
;
1014 QSIMPLEQ_INSERT_TAIL(&stream
->queue
, buffer
, entry
);
1019 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1020 must_empty_invalid_queue
= true;
1021 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
));
1022 buffer
->elem
= elem
;
1024 QSIMPLEQ_INSERT_TAIL(&stream
->invalid
, buffer
, entry
);
1028 if (must_empty_invalid_queue
) {
1029 empty_invalid_queue(vdev
, vq
);
1033 static uint64_t get_features(VirtIODevice
*vdev
, uint64_t features
,
1037 * virtio-v1.2-csd01, 5.14.3,
1039 * None currently defined.
1041 VirtIOSound
*s
= VIRTIO_SND(vdev
);
1042 features
|= s
->features
;
1044 trace_virtio_snd_get_features(vdev
, features
);
1050 virtio_snd_vm_state_change(void *opaque
, bool running
,
1054 trace_virtio_snd_vm_state_running();
1056 trace_virtio_snd_vm_state_stopped();
1060 static void virtio_snd_realize(DeviceState
*dev
, Error
**errp
)
1063 VirtIOSound
*vsnd
= VIRTIO_SND(dev
);
1064 VirtIODevice
*vdev
= VIRTIO_DEVICE(dev
);
1065 virtio_snd_pcm_set_params default_params
= { 0 };
1070 qemu_add_vm_change_state_handler(virtio_snd_vm_state_change
, vsnd
);
1072 trace_virtio_snd_realize(vsnd
);
1074 vsnd
->pcm
= g_new0(VirtIOSoundPCM
, 1);
1075 vsnd
->pcm
->snd
= vsnd
;
1076 vsnd
->pcm
->streams
=
1077 g_new0(VirtIOSoundPCMStream
*, vsnd
->snd_conf
.streams
);
1078 vsnd
->pcm
->pcm_params
=
1079 g_new0(virtio_snd_pcm_set_params
, vsnd
->snd_conf
.streams
);
1081 virtio_init(vdev
, VIRTIO_ID_SOUND
, sizeof(virtio_snd_config
));
1082 virtio_add_feature(&vsnd
->features
, VIRTIO_F_VERSION_1
);
1084 /* set number of jacks and streams */
1085 if (vsnd
->snd_conf
.jacks
> 8) {
1087 "Invalid number of jacks: %"PRIu32
,
1088 vsnd
->snd_conf
.jacks
);
1091 if (vsnd
->snd_conf
.streams
< 1 || vsnd
->snd_conf
.streams
> 10) {
1093 "Invalid number of streams: %"PRIu32
,
1094 vsnd
->snd_conf
.streams
);
1098 if (vsnd
->snd_conf
.chmaps
> VIRTIO_SND_CHMAP_MAX_SIZE
) {
1100 "Invalid number of channel maps: %"PRIu32
,
1101 vsnd
->snd_conf
.chmaps
);
1105 if (!AUD_register_card("virtio-sound", &vsnd
->card
, errp
)) {
1109 /* set default params for all streams */
1110 default_params
.features
= 0;
1111 default_params
.buffer_bytes
= cpu_to_le32(8192);
1112 default_params
.period_bytes
= cpu_to_le32(2048);
1113 default_params
.channels
= 2;
1114 default_params
.format
= VIRTIO_SND_PCM_FMT_S16
;
1115 default_params
.rate
= VIRTIO_SND_PCM_RATE_48000
;
1116 vsnd
->queues
[VIRTIO_SND_VQ_CONTROL
] =
1117 virtio_add_queue(vdev
, 64, virtio_snd_handle_ctrl
);
1118 vsnd
->queues
[VIRTIO_SND_VQ_EVENT
] =
1119 virtio_add_queue(vdev
, 64, virtio_snd_handle_event
);
1120 vsnd
->queues
[VIRTIO_SND_VQ_TX
] =
1121 virtio_add_queue(vdev
, 64, virtio_snd_handle_tx_xfer
);
1122 vsnd
->queues
[VIRTIO_SND_VQ_RX
] =
1123 virtio_add_queue(vdev
, 64, virtio_snd_handle_rx_xfer
);
1124 qemu_mutex_init(&vsnd
->cmdq_mutex
);
1125 QTAILQ_INIT(&vsnd
->cmdq
);
1127 for (uint32_t i
= 0; i
< vsnd
->snd_conf
.streams
; i
++) {
1128 status
= virtio_snd_set_pcm_params(vsnd
, i
, &default_params
);
1129 if (status
!= cpu_to_le32(VIRTIO_SND_S_OK
)) {
1131 "Can't initialize stream params, device responded with %s.",
1132 print_code(status
));
1135 status
= virtio_snd_pcm_prepare(vsnd
, i
);
1136 if (status
!= cpu_to_le32(VIRTIO_SND_S_OK
)) {
1138 "Can't prepare streams, device responded with %s.",
1139 print_code(status
));
1145 static inline void return_tx_buffer(VirtIOSoundPCMStream
*stream
,
1146 VirtIOSoundPCMBuffer
*buffer
)
1148 virtio_snd_pcm_status resp
= { 0 };
1149 resp
.status
= cpu_to_le32(VIRTIO_SND_S_OK
);
1150 resp
.latency_bytes
= cpu_to_le32((uint32_t)buffer
->size
);
1151 iov_from_buf(buffer
->elem
->in_sg
,
1152 buffer
->elem
->in_num
,
1155 sizeof(virtio_snd_pcm_status
));
1156 virtqueue_push(buffer
->vq
,
1158 sizeof(virtio_snd_pcm_status
));
1159 virtio_notify(VIRTIO_DEVICE(stream
->s
), buffer
->vq
);
1160 QSIMPLEQ_REMOVE(&stream
->queue
,
1162 VirtIOSoundPCMBuffer
,
1164 virtio_snd_pcm_buffer_free(buffer
);
1168 * AUD_* output callback.
1170 * @data: VirtIOSoundPCMStream stream
1171 * @available: number of bytes that can be written with AUD_write()
1173 static void virtio_snd_pcm_out_cb(void *data
, int available
)
1175 VirtIOSoundPCMStream
*stream
= data
;
1176 VirtIOSoundPCMBuffer
*buffer
;
1179 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1180 while (!QSIMPLEQ_EMPTY(&stream
->queue
)) {
1181 buffer
= QSIMPLEQ_FIRST(&stream
->queue
);
1182 if (!virtio_queue_ready(buffer
->vq
)) {
1185 if (!stream
->active
) {
1186 /* Stream has stopped, so do not perform AUD_write. */
1187 return_tx_buffer(stream
, buffer
);
1190 if (!buffer
->populated
) {
1191 iov_to_buf(buffer
->elem
->out_sg
,
1192 buffer
->elem
->out_num
,
1193 sizeof(virtio_snd_pcm_xfer
),
1196 buffer
->populated
= true;
1199 size
= AUD_write(stream
->voice
.out
,
1200 buffer
->data
+ buffer
->offset
,
1201 MIN(buffer
->size
, available
));
1202 assert(size
<= MIN(buffer
->size
, available
));
1204 /* break out of both loops */
1208 buffer
->size
-= size
;
1209 buffer
->offset
+= size
;
1211 if (buffer
->size
< 1) {
1212 return_tx_buffer(stream
, buffer
);
1227 * Flush all buffer data from this input stream's queue into the driver's
1230 * @stream: VirtIOSoundPCMStream *stream
1232 static inline void return_rx_buffer(VirtIOSoundPCMStream
*stream
,
1233 VirtIOSoundPCMBuffer
*buffer
)
1235 virtio_snd_pcm_status resp
= { 0 };
1236 resp
.status
= cpu_to_le32(VIRTIO_SND_S_OK
);
1237 resp
.latency_bytes
= 0;
1238 /* Copy data -if any- to guest */
1239 iov_from_buf(buffer
->elem
->in_sg
,
1240 buffer
->elem
->in_num
,
1244 iov_from_buf(buffer
->elem
->in_sg
,
1245 buffer
->elem
->in_num
,
1248 sizeof(virtio_snd_pcm_status
));
1249 virtqueue_push(buffer
->vq
,
1251 sizeof(virtio_snd_pcm_status
) + buffer
->size
);
1252 virtio_notify(VIRTIO_DEVICE(stream
->s
), buffer
->vq
);
1253 QSIMPLEQ_REMOVE(&stream
->queue
,
1255 VirtIOSoundPCMBuffer
,
1257 virtio_snd_pcm_buffer_free(buffer
);
1262 * AUD_* input callback.
1264 * @data: VirtIOSoundPCMStream stream
1265 * @available: number of bytes that can be read with AUD_read()
1267 static void virtio_snd_pcm_in_cb(void *data
, int available
)
1269 VirtIOSoundPCMStream
*stream
= data
;
1270 VirtIOSoundPCMBuffer
*buffer
;
1273 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1274 while (!QSIMPLEQ_EMPTY(&stream
->queue
)) {
1275 buffer
= QSIMPLEQ_FIRST(&stream
->queue
);
1276 if (!virtio_queue_ready(buffer
->vq
)) {
1279 if (!stream
->active
) {
1280 /* Stream has stopped, so do not perform AUD_read. */
1281 return_rx_buffer(stream
, buffer
);
1286 size
= AUD_read(stream
->voice
.in
,
1287 buffer
->data
+ buffer
->size
,
1288 MIN(available
, (stream
->params
.period_bytes
-
1294 buffer
->size
+= size
;
1296 if (buffer
->size
>= stream
->params
.period_bytes
) {
1297 return_rx_buffer(stream
, buffer
);
1312 * Flush all buffer data from this output stream's queue into the driver's
1315 * @stream: VirtIOSoundPCMStream *stream
1317 static inline void virtio_snd_pcm_flush(VirtIOSoundPCMStream
*stream
)
1319 VirtIOSoundPCMBuffer
*buffer
;
1320 void (*cb
)(VirtIOSoundPCMStream
*, VirtIOSoundPCMBuffer
*) =
1321 (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) ? return_tx_buffer
:
1324 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1325 while (!QSIMPLEQ_EMPTY(&stream
->queue
)) {
1326 buffer
= QSIMPLEQ_FIRST(&stream
->queue
);
1332 static void virtio_snd_unrealize(DeviceState
*dev
)
1334 VirtIODevice
*vdev
= VIRTIO_DEVICE(dev
);
1335 VirtIOSound
*vsnd
= VIRTIO_SND(dev
);
1336 VirtIOSoundPCMStream
*stream
;
1338 qemu_del_vm_change_state_handler(vsnd
->vmstate
);
1339 trace_virtio_snd_unrealize(vsnd
);
1342 if (vsnd
->pcm
->streams
) {
1343 for (uint32_t i
= 0; i
< vsnd
->snd_conf
.streams
; i
++) {
1344 stream
= vsnd
->pcm
->streams
[i
];
1346 virtio_snd_process_cmdq(stream
->s
);
1347 virtio_snd_pcm_close(stream
);
1348 qemu_mutex_destroy(&stream
->queue_mutex
);
1352 g_free(vsnd
->pcm
->streams
);
1354 g_free(vsnd
->pcm
->pcm_params
);
1358 AUD_remove_card(&vsnd
->card
);
1359 qemu_mutex_destroy(&vsnd
->cmdq_mutex
);
1360 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_CONTROL
]);
1361 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_EVENT
]);
1362 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_TX
]);
1363 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_RX
]);
1364 virtio_cleanup(vdev
);
1368 static void virtio_snd_reset(VirtIODevice
*vdev
)
1370 VirtIOSound
*s
= VIRTIO_SND(vdev
);
1371 virtio_snd_ctrl_command
*cmd
;
1373 WITH_QEMU_LOCK_GUARD(&s
->cmdq_mutex
) {
1374 while (!QTAILQ_EMPTY(&s
->cmdq
)) {
1375 cmd
= QTAILQ_FIRST(&s
->cmdq
);
1376 QTAILQ_REMOVE(&s
->cmdq
, cmd
, next
);
1377 virtio_snd_ctrl_cmd_free(cmd
);
1382 static void virtio_snd_class_init(ObjectClass
*klass
, void *data
)
1384 DeviceClass
*dc
= DEVICE_CLASS(klass
);
1385 VirtioDeviceClass
*vdc
= VIRTIO_DEVICE_CLASS(klass
);
1388 set_bit(DEVICE_CATEGORY_SOUND
, dc
->categories
);
1389 device_class_set_props(dc
, virtio_snd_properties
);
1391 dc
->vmsd
= &vmstate_virtio_snd
;
1392 vdc
->vmsd
= &vmstate_virtio_snd_device
;
1393 vdc
->realize
= virtio_snd_realize
;
1394 vdc
->unrealize
= virtio_snd_unrealize
;
1395 vdc
->get_config
= virtio_snd_get_config
;
1396 vdc
->set_config
= virtio_snd_set_config
;
1397 vdc
->get_features
= get_features
;
1398 vdc
->reset
= virtio_snd_reset
;
1399 vdc
->legacy_features
= 0;
1402 static const TypeInfo virtio_snd_types
[] = {
1404 .name
= TYPE_VIRTIO_SND
,
1405 .parent
= TYPE_VIRTIO_DEVICE
,
1406 .instance_size
= sizeof(VirtIOSound
),
1407 .class_init
= virtio_snd_class_init
,
1411 DEFINE_TYPES(virtio_snd_types
)