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 "qemu/lockable.h"
23 #include "exec/tswap.h"
24 #include "sysemu/runstate.h"
26 #include "qapi/error.h"
27 #include "hw/audio/virtio-snd.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
= (const 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
->payload_size
= sizeof(virtio_snd_pcm_info
) * count
;
247 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
248 iov_from_buf(cmd
->elem
->in_sg
,
250 sizeof(virtio_snd_hdr
),
256 * Set the given stream params.
257 * Called by both virtio_snd_handle_pcm_set_params and during device
259 * Returns the response status code. (VIRTIO_SND_S_*).
261 * @s: VirtIOSound device
262 * @params: The PCM params as defined in the virtio specification
265 uint32_t virtio_snd_set_pcm_params(VirtIOSound
*s
,
267 virtio_snd_pcm_set_params
*params
)
269 virtio_snd_pcm_set_params
*st_params
;
271 if (stream_id
>= s
->snd_conf
.streams
|| s
->pcm
->pcm_params
== NULL
) {
273 * TODO: do we need to set DEVICE_NEEDS_RESET?
275 virtio_error(VIRTIO_DEVICE(s
), "Streams have not been initialized.\n");
276 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
279 st_params
= virtio_snd_pcm_get_params(s
, stream_id
);
281 if (params
->channels
< 1 || params
->channels
> AUDIO_MAX_CHANNELS
) {
282 error_report("Number of channels is not supported.");
283 return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
285 if (!(supported_formats
& BIT(params
->format
))) {
286 error_report("Stream format is not supported.");
287 return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
289 if (!(supported_rates
& BIT(params
->rate
))) {
290 error_report("Stream rate is not supported.");
291 return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
294 st_params
->buffer_bytes
= le32_to_cpu(params
->buffer_bytes
);
295 st_params
->period_bytes
= le32_to_cpu(params
->period_bytes
);
296 st_params
->features
= le32_to_cpu(params
->features
);
297 /* the following are uint8_t, so there's no need to bswap the values. */
298 st_params
->channels
= params
->channels
;
299 st_params
->format
= params
->format
;
300 st_params
->rate
= params
->rate
;
302 return cpu_to_le32(VIRTIO_SND_S_OK
);
306 * Handles the VIRTIO_SND_R_PCM_SET_PARAMS request.
308 * @s: VirtIOSound device
309 * @cmd: The request command queue element from VirtIOSound cmdq field
311 static void virtio_snd_handle_pcm_set_params(VirtIOSound
*s
,
312 virtio_snd_ctrl_command
*cmd
)
314 virtio_snd_pcm_set_params req
= { 0 };
316 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
320 sizeof(virtio_snd_pcm_set_params
));
322 if (msg_sz
!= sizeof(virtio_snd_pcm_set_params
)) {
324 * TODO: do we need to set DEVICE_NEEDS_RESET?
326 qemu_log_mask(LOG_GUEST_ERROR
,
327 "%s: virtio-snd command size incorrect %zu vs \
328 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_pcm_set_params
));
329 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
332 stream_id
= le32_to_cpu(req
.hdr
.stream_id
);
333 trace_virtio_snd_handle_pcm_set_params(stream_id
);
334 cmd
->resp
.code
= virtio_snd_set_pcm_params(s
, stream_id
, &req
);
338 * Get a QEMU Audiosystem compatible format value from a VIRTIO_SND_PCM_FMT_*
340 static AudioFormat
virtio_snd_get_qemu_format(uint32_t format
)
343 case VIRTIO_SND_PCM_FMT_##FMT: \
344 return AUDIO_FORMAT_##FMT;
353 case VIRTIO_SND_PCM_FMT_FLOAT
:
354 return AUDIO_FORMAT_F32
;
356 g_assert_not_reached();
363 * Get a QEMU Audiosystem compatible frequency value from a
364 * VIRTIO_SND_PCM_RATE_*
366 static uint32_t virtio_snd_get_qemu_freq(uint32_t rate
)
369 case VIRTIO_SND_PCM_RATE_##RATE: \
388 g_assert_not_reached();
395 * Get QEMU Audiosystem compatible audsettings from virtio based pcm stream
398 static void virtio_snd_get_qemu_audsettings(audsettings
*as
,
399 virtio_snd_pcm_set_params
*params
)
401 as
->nchannels
= MIN(AUDIO_MAX_CHANNELS
, params
->channels
);
402 as
->fmt
= virtio_snd_get_qemu_format(params
->format
);
403 as
->freq
= virtio_snd_get_qemu_freq(params
->rate
);
404 as
->endianness
= target_words_bigendian() ? 1 : 0;
408 * Close a stream and free all its resources.
410 * @stream: VirtIOSoundPCMStream *stream
412 static void virtio_snd_pcm_close(VirtIOSoundPCMStream
*stream
)
415 virtio_snd_pcm_flush(stream
);
416 if (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) {
417 AUD_close_out(&stream
->pcm
->snd
->card
, stream
->voice
.out
);
418 stream
->voice
.out
= NULL
;
419 } else if (stream
->info
.direction
== VIRTIO_SND_D_INPUT
) {
420 AUD_close_in(&stream
->pcm
->snd
->card
, stream
->voice
.in
);
421 stream
->voice
.in
= NULL
;
427 * Prepares a VirtIOSound card stream.
428 * Returns the response status code. (VIRTIO_SND_S_*).
430 * @s: VirtIOSound device
431 * @stream_id: stream id
433 static uint32_t virtio_snd_pcm_prepare(VirtIOSound
*s
, uint32_t stream_id
)
436 virtio_snd_pcm_set_params
*params
;
437 VirtIOSoundPCMStream
*stream
;
439 if (s
->pcm
->streams
== NULL
||
440 s
->pcm
->pcm_params
== NULL
||
441 stream_id
>= s
->snd_conf
.streams
) {
442 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
445 params
= virtio_snd_pcm_get_params(s
, stream_id
);
446 if (params
== NULL
) {
447 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
450 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
451 if (stream
== NULL
) {
452 stream
= g_new0(VirtIOSoundPCMStream
, 1);
453 stream
->active
= false;
454 stream
->id
= stream_id
;
455 stream
->pcm
= s
->pcm
;
457 qemu_mutex_init(&stream
->queue_mutex
);
458 QSIMPLEQ_INIT(&stream
->queue
);
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
) {
618 * Handles VIRTIO_SND_R_PCM_RELEASE.
620 * @s: VirtIOSound device
621 * @cmd: The request command queue element from VirtIOSound cmdq field
623 static void virtio_snd_handle_pcm_release(VirtIOSound
*s
,
624 virtio_snd_ctrl_command
*cmd
)
627 VirtIOSoundPCMStream
*stream
;
628 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
630 sizeof(virtio_snd_hdr
),
634 if (msg_sz
!= sizeof(stream_id
)) {
636 * TODO: do we need to set DEVICE_NEEDS_RESET?
638 qemu_log_mask(LOG_GUEST_ERROR
,
639 "%s: virtio-snd command size incorrect %zu vs \
640 %zu\n", __func__
, msg_sz
, sizeof(stream_id
));
641 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
645 stream_id
= le32_to_cpu(stream_id
);
646 trace_virtio_snd_handle_pcm_release(stream_id
);
647 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
648 if (stream
== NULL
) {
650 * TODO: do we need to set DEVICE_NEEDS_RESET?
652 error_report("already released stream %"PRIu32
, stream_id
);
653 virtio_error(VIRTIO_DEVICE(s
),
654 "already released stream %"PRIu32
,
656 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
660 if (virtio_snd_pcm_get_io_msgs_count(stream
)) {
662 * virtio-v1.2-csd01, 5.14.6.6.5.1,
663 * Device Requirements: Stream Release
665 * - The device MUST complete all pending I/O messages for the
666 * specified stream ID.
667 * - The device MUST NOT complete the control request while there
668 * are pending I/O messages for the specified stream ID.
670 trace_virtio_snd_pcm_stream_flush(stream_id
);
671 virtio_snd_pcm_flush(stream
);
674 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
678 * The actual processing done in virtio_snd_process_cmdq().
680 * @s: VirtIOSound device
681 * @cmd: control command request
684 process_cmd(VirtIOSound
*s
, virtio_snd_ctrl_command
*cmd
)
687 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
691 sizeof(virtio_snd_hdr
));
693 if (msg_sz
!= sizeof(virtio_snd_hdr
)) {
695 * TODO: do we need to set DEVICE_NEEDS_RESET?
697 qemu_log_mask(LOG_GUEST_ERROR
,
698 "%s: virtio-snd command size incorrect %zu vs \
699 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_hdr
));
703 code
= le32_to_cpu(cmd
->ctrl
.code
);
705 trace_virtio_snd_handle_code(code
, print_code(code
));
708 case VIRTIO_SND_R_JACK_INFO
:
709 case VIRTIO_SND_R_JACK_REMAP
:
710 qemu_log_mask(LOG_UNIMP
,
711 "virtio_snd: jack functionality is unimplemented.\n");
712 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
714 case VIRTIO_SND_R_PCM_INFO
:
715 virtio_snd_handle_pcm_info(s
, cmd
);
717 case VIRTIO_SND_R_PCM_START
:
718 virtio_snd_handle_pcm_start_stop(s
, cmd
, true);
720 case VIRTIO_SND_R_PCM_STOP
:
721 virtio_snd_handle_pcm_start_stop(s
, cmd
, false);
723 case VIRTIO_SND_R_PCM_SET_PARAMS
:
724 virtio_snd_handle_pcm_set_params(s
, cmd
);
726 case VIRTIO_SND_R_PCM_PREPARE
:
727 virtio_snd_handle_pcm_prepare(s
, cmd
);
729 case VIRTIO_SND_R_PCM_RELEASE
:
730 virtio_snd_handle_pcm_release(s
, cmd
);
732 case VIRTIO_SND_R_CHMAP_INFO
:
733 qemu_log_mask(LOG_UNIMP
,
734 "virtio_snd: chmap info functionality is unimplemented.\n");
735 trace_virtio_snd_handle_chmap_info();
736 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
740 error_report("virtio snd header not recognized: %"PRIu32
, code
);
741 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
744 iov_from_buf(cmd
->elem
->in_sg
,
748 sizeof(virtio_snd_hdr
));
749 virtqueue_push(cmd
->vq
, cmd
->elem
,
750 sizeof(virtio_snd_hdr
) + cmd
->payload_size
);
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 /* implicit cmd->payload_size = 0; */
810 QTAILQ_INSERT_TAIL(&s
->cmdq
, cmd
, next
);
811 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
814 virtio_snd_process_cmdq(s
);
818 * The event virtqueue handler.
819 * Not implemented yet.
821 * @vdev: VirtIOSound device
824 static void virtio_snd_handle_event(VirtIODevice
*vdev
, VirtQueue
*vq
)
826 qemu_log_mask(LOG_UNIMP
, "virtio_snd: event queue is unimplemented.\n");
827 trace_virtio_snd_handle_event();
831 * Must only be called if vsnd->invalid is not empty.
833 static inline void empty_invalid_queue(VirtIODevice
*vdev
, VirtQueue
*vq
)
835 VirtIOSoundPCMBuffer
*buffer
= NULL
;
836 virtio_snd_pcm_status resp
= { 0 };
837 VirtIOSound
*vsnd
= VIRTIO_SND(vdev
);
839 g_assert(!QSIMPLEQ_EMPTY(&vsnd
->invalid
));
841 while (!QSIMPLEQ_EMPTY(&vsnd
->invalid
)) {
842 buffer
= QSIMPLEQ_FIRST(&vsnd
->invalid
);
843 /* If buffer->vq != vq, our logic is fundamentally wrong, so bail out */
844 g_assert(buffer
->vq
== vq
);
846 resp
.status
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
847 iov_from_buf(buffer
->elem
->in_sg
,
848 buffer
->elem
->in_num
,
851 sizeof(virtio_snd_pcm_status
));
854 sizeof(virtio_snd_pcm_status
));
855 QSIMPLEQ_REMOVE_HEAD(&vsnd
->invalid
, entry
);
856 virtio_snd_pcm_buffer_free(buffer
);
858 /* Notify vq about virtio_snd_pcm_status responses. */
859 virtio_notify(vdev
, vq
);
863 * The tx virtqueue handler. Makes the buffers available to their respective
864 * streams for consumption.
866 * @vdev: VirtIOSound device
869 static void virtio_snd_handle_tx_xfer(VirtIODevice
*vdev
, VirtQueue
*vq
)
871 VirtIOSound
*vsnd
= VIRTIO_SND(vdev
);
872 VirtIOSoundPCMBuffer
*buffer
;
873 VirtQueueElement
*elem
;
875 virtio_snd_pcm_xfer hdr
;
878 * If any of the I/O messages are invalid, put them in vsnd->invalid and
879 * return them after the for loop.
881 bool must_empty_invalid_queue
= false;
883 if (!virtio_queue_ready(vq
)) {
886 trace_virtio_snd_handle_tx_xfer();
889 VirtIOSoundPCMStream
*stream
;
891 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
895 /* get the message hdr object */
896 msg_sz
= iov_to_buf(elem
->out_sg
,
900 sizeof(virtio_snd_pcm_xfer
));
901 if (msg_sz
!= sizeof(virtio_snd_pcm_xfer
)) {
904 stream_id
= le32_to_cpu(hdr
.stream_id
);
906 if (stream_id
>= vsnd
->snd_conf
.streams
907 || vsnd
->pcm
->streams
[stream_id
] == NULL
) {
911 stream
= vsnd
->pcm
->streams
[stream_id
];
912 if (stream
->info
.direction
!= VIRTIO_SND_D_OUTPUT
) {
916 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
917 size
= iov_size(elem
->out_sg
, elem
->out_num
) - msg_sz
;
919 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
) + size
);
921 buffer
->populated
= false;
926 QSIMPLEQ_INSERT_TAIL(&stream
->queue
, buffer
, entry
);
931 must_empty_invalid_queue
= true;
932 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
));
935 QSIMPLEQ_INSERT_TAIL(&vsnd
->invalid
, buffer
, entry
);
938 if (must_empty_invalid_queue
) {
939 empty_invalid_queue(vdev
, vq
);
944 * The rx virtqueue handler. Makes the buffers available to their respective
945 * streams for consumption.
947 * @vdev: VirtIOSound device
950 static void virtio_snd_handle_rx_xfer(VirtIODevice
*vdev
, VirtQueue
*vq
)
952 VirtIOSound
*vsnd
= VIRTIO_SND(vdev
);
953 VirtIOSoundPCMBuffer
*buffer
;
954 VirtQueueElement
*elem
;
956 virtio_snd_pcm_xfer hdr
;
959 * if any of the I/O messages are invalid, put them in vsnd->invalid and
960 * return them after the for loop.
962 bool must_empty_invalid_queue
= false;
964 if (!virtio_queue_ready(vq
)) {
967 trace_virtio_snd_handle_rx_xfer();
970 VirtIOSoundPCMStream
*stream
;
972 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
976 /* get the message hdr object */
977 msg_sz
= iov_to_buf(elem
->out_sg
,
981 sizeof(virtio_snd_pcm_xfer
));
982 if (msg_sz
!= sizeof(virtio_snd_pcm_xfer
)) {
985 stream_id
= le32_to_cpu(hdr
.stream_id
);
987 if (stream_id
>= vsnd
->snd_conf
.streams
988 || !vsnd
->pcm
->streams
[stream_id
]) {
992 stream
= vsnd
->pcm
->streams
[stream_id
];
993 if (stream
== NULL
|| stream
->info
.direction
!= VIRTIO_SND_D_INPUT
) {
996 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
997 size
= iov_size(elem
->in_sg
, elem
->in_num
) -
998 sizeof(virtio_snd_pcm_status
);
999 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
) + size
);
1000 buffer
->elem
= elem
;
1004 QSIMPLEQ_INSERT_TAIL(&stream
->queue
, buffer
, entry
);
1009 must_empty_invalid_queue
= true;
1010 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
));
1011 buffer
->elem
= elem
;
1013 QSIMPLEQ_INSERT_TAIL(&vsnd
->invalid
, buffer
, entry
);
1016 if (must_empty_invalid_queue
) {
1017 empty_invalid_queue(vdev
, vq
);
1021 static uint64_t get_features(VirtIODevice
*vdev
, uint64_t features
,
1025 * virtio-v1.2-csd01, 5.14.3,
1027 * None currently defined.
1029 VirtIOSound
*s
= VIRTIO_SND(vdev
);
1030 features
|= s
->features
;
1032 trace_virtio_snd_get_features(vdev
, features
);
1038 virtio_snd_vm_state_change(void *opaque
, bool running
,
1042 trace_virtio_snd_vm_state_running();
1044 trace_virtio_snd_vm_state_stopped();
1048 static void virtio_snd_realize(DeviceState
*dev
, Error
**errp
)
1051 VirtIOSound
*vsnd
= VIRTIO_SND(dev
);
1052 VirtIODevice
*vdev
= VIRTIO_DEVICE(dev
);
1053 virtio_snd_pcm_set_params default_params
= { 0 };
1056 trace_virtio_snd_realize(vsnd
);
1058 /* check number of jacks and streams */
1059 if (vsnd
->snd_conf
.jacks
> 8) {
1061 "Invalid number of jacks: %"PRIu32
,
1062 vsnd
->snd_conf
.jacks
);
1065 if (vsnd
->snd_conf
.streams
< 1 || vsnd
->snd_conf
.streams
> 10) {
1067 "Invalid number of streams: %"PRIu32
,
1068 vsnd
->snd_conf
.streams
);
1072 if (vsnd
->snd_conf
.chmaps
> VIRTIO_SND_CHMAP_MAX_SIZE
) {
1074 "Invalid number of channel maps: %"PRIu32
,
1075 vsnd
->snd_conf
.chmaps
);
1079 if (!AUD_register_card("virtio-sound", &vsnd
->card
, errp
)) {
1084 qemu_add_vm_change_state_handler(virtio_snd_vm_state_change
, vsnd
);
1086 vsnd
->pcm
= g_new0(VirtIOSoundPCM
, 1);
1087 vsnd
->pcm
->snd
= vsnd
;
1088 vsnd
->pcm
->streams
=
1089 g_new0(VirtIOSoundPCMStream
*, vsnd
->snd_conf
.streams
);
1090 vsnd
->pcm
->pcm_params
=
1091 g_new0(virtio_snd_pcm_set_params
, vsnd
->snd_conf
.streams
);
1093 virtio_init(vdev
, VIRTIO_ID_SOUND
, sizeof(virtio_snd_config
));
1094 virtio_add_feature(&vsnd
->features
, VIRTIO_F_VERSION_1
);
1096 /* set default params for all streams */
1097 default_params
.features
= 0;
1098 default_params
.buffer_bytes
= cpu_to_le32(8192);
1099 default_params
.period_bytes
= cpu_to_le32(2048);
1100 default_params
.channels
= 2;
1101 default_params
.format
= VIRTIO_SND_PCM_FMT_S16
;
1102 default_params
.rate
= VIRTIO_SND_PCM_RATE_48000
;
1103 vsnd
->queues
[VIRTIO_SND_VQ_CONTROL
] =
1104 virtio_add_queue(vdev
, 64, virtio_snd_handle_ctrl
);
1105 vsnd
->queues
[VIRTIO_SND_VQ_EVENT
] =
1106 virtio_add_queue(vdev
, 64, virtio_snd_handle_event
);
1107 vsnd
->queues
[VIRTIO_SND_VQ_TX
] =
1108 virtio_add_queue(vdev
, 64, virtio_snd_handle_tx_xfer
);
1109 vsnd
->queues
[VIRTIO_SND_VQ_RX
] =
1110 virtio_add_queue(vdev
, 64, virtio_snd_handle_rx_xfer
);
1111 qemu_mutex_init(&vsnd
->cmdq_mutex
);
1112 QTAILQ_INIT(&vsnd
->cmdq
);
1113 QSIMPLEQ_INIT(&vsnd
->invalid
);
1115 for (uint32_t i
= 0; i
< vsnd
->snd_conf
.streams
; i
++) {
1116 status
= virtio_snd_set_pcm_params(vsnd
, i
, &default_params
);
1117 if (status
!= cpu_to_le32(VIRTIO_SND_S_OK
)) {
1119 "Can't initialize stream params, device responded with %s.",
1120 print_code(status
));
1123 status
= virtio_snd_pcm_prepare(vsnd
, i
);
1124 if (status
!= cpu_to_le32(VIRTIO_SND_S_OK
)) {
1126 "Can't prepare streams, device responded with %s.",
1127 print_code(status
));
1135 virtio_snd_unrealize(dev
);
1138 static inline void return_tx_buffer(VirtIOSoundPCMStream
*stream
,
1139 VirtIOSoundPCMBuffer
*buffer
)
1141 virtio_snd_pcm_status resp
= { 0 };
1142 resp
.status
= cpu_to_le32(VIRTIO_SND_S_OK
);
1143 resp
.latency_bytes
= cpu_to_le32((uint32_t)buffer
->size
);
1144 iov_from_buf(buffer
->elem
->in_sg
,
1145 buffer
->elem
->in_num
,
1148 sizeof(virtio_snd_pcm_status
));
1149 virtqueue_push(buffer
->vq
,
1151 sizeof(virtio_snd_pcm_status
));
1152 virtio_notify(VIRTIO_DEVICE(stream
->s
), buffer
->vq
);
1153 QSIMPLEQ_REMOVE(&stream
->queue
,
1155 VirtIOSoundPCMBuffer
,
1157 virtio_snd_pcm_buffer_free(buffer
);
1161 * AUD_* output callback.
1163 * @data: VirtIOSoundPCMStream stream
1164 * @available: number of bytes that can be written with AUD_write()
1166 static void virtio_snd_pcm_out_cb(void *data
, int available
)
1168 VirtIOSoundPCMStream
*stream
= data
;
1169 VirtIOSoundPCMBuffer
*buffer
;
1172 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1173 while (!QSIMPLEQ_EMPTY(&stream
->queue
)) {
1174 buffer
= QSIMPLEQ_FIRST(&stream
->queue
);
1175 if (!virtio_queue_ready(buffer
->vq
)) {
1178 if (!stream
->active
) {
1179 /* Stream has stopped, so do not perform AUD_write. */
1180 return_tx_buffer(stream
, buffer
);
1183 if (!buffer
->populated
) {
1184 iov_to_buf(buffer
->elem
->out_sg
,
1185 buffer
->elem
->out_num
,
1186 sizeof(virtio_snd_pcm_xfer
),
1189 buffer
->populated
= true;
1192 size
= AUD_write(stream
->voice
.out
,
1193 buffer
->data
+ buffer
->offset
,
1194 MIN(buffer
->size
, available
));
1195 assert(size
<= MIN(buffer
->size
, available
));
1197 /* break out of both loops */
1201 buffer
->size
-= size
;
1202 buffer
->offset
+= size
;
1204 if (buffer
->size
< 1) {
1205 return_tx_buffer(stream
, buffer
);
1220 * Flush all buffer data from this input stream's queue into the driver's
1223 * @stream: VirtIOSoundPCMStream *stream
1225 static inline void return_rx_buffer(VirtIOSoundPCMStream
*stream
,
1226 VirtIOSoundPCMBuffer
*buffer
)
1228 virtio_snd_pcm_status resp
= { 0 };
1229 resp
.status
= cpu_to_le32(VIRTIO_SND_S_OK
);
1230 resp
.latency_bytes
= 0;
1231 /* Copy data -if any- to guest */
1232 iov_from_buf(buffer
->elem
->in_sg
,
1233 buffer
->elem
->in_num
,
1237 iov_from_buf(buffer
->elem
->in_sg
,
1238 buffer
->elem
->in_num
,
1241 sizeof(virtio_snd_pcm_status
));
1242 virtqueue_push(buffer
->vq
,
1244 sizeof(virtio_snd_pcm_status
) + buffer
->size
);
1245 virtio_notify(VIRTIO_DEVICE(stream
->s
), buffer
->vq
);
1246 QSIMPLEQ_REMOVE(&stream
->queue
,
1248 VirtIOSoundPCMBuffer
,
1250 virtio_snd_pcm_buffer_free(buffer
);
1255 * AUD_* input callback.
1257 * @data: VirtIOSoundPCMStream stream
1258 * @available: number of bytes that can be read with AUD_read()
1260 static void virtio_snd_pcm_in_cb(void *data
, int available
)
1262 VirtIOSoundPCMStream
*stream
= data
;
1263 VirtIOSoundPCMBuffer
*buffer
;
1266 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1267 while (!QSIMPLEQ_EMPTY(&stream
->queue
)) {
1268 buffer
= QSIMPLEQ_FIRST(&stream
->queue
);
1269 if (!virtio_queue_ready(buffer
->vq
)) {
1272 if (!stream
->active
) {
1273 /* Stream has stopped, so do not perform AUD_read. */
1274 return_rx_buffer(stream
, buffer
);
1279 size
= AUD_read(stream
->voice
.in
,
1280 buffer
->data
+ buffer
->size
,
1281 MIN(available
, (stream
->params
.period_bytes
-
1287 buffer
->size
+= size
;
1289 if (buffer
->size
>= stream
->params
.period_bytes
) {
1290 return_rx_buffer(stream
, buffer
);
1305 * Flush all buffer data from this output stream's queue into the driver's
1308 * @stream: VirtIOSoundPCMStream *stream
1310 static inline void virtio_snd_pcm_flush(VirtIOSoundPCMStream
*stream
)
1312 VirtIOSoundPCMBuffer
*buffer
;
1313 void (*cb
)(VirtIOSoundPCMStream
*, VirtIOSoundPCMBuffer
*) =
1314 (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) ? return_tx_buffer
:
1317 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1318 while (!QSIMPLEQ_EMPTY(&stream
->queue
)) {
1319 buffer
= QSIMPLEQ_FIRST(&stream
->queue
);
1325 static void virtio_snd_unrealize(DeviceState
*dev
)
1327 VirtIODevice
*vdev
= VIRTIO_DEVICE(dev
);
1328 VirtIOSound
*vsnd
= VIRTIO_SND(dev
);
1329 VirtIOSoundPCMStream
*stream
;
1331 qemu_del_vm_change_state_handler(vsnd
->vmstate
);
1332 trace_virtio_snd_unrealize(vsnd
);
1335 if (vsnd
->pcm
->streams
) {
1336 for (uint32_t i
= 0; i
< vsnd
->snd_conf
.streams
; i
++) {
1337 stream
= vsnd
->pcm
->streams
[i
];
1339 virtio_snd_process_cmdq(stream
->s
);
1340 virtio_snd_pcm_close(stream
);
1341 qemu_mutex_destroy(&stream
->queue_mutex
);
1345 g_free(vsnd
->pcm
->streams
);
1347 g_free(vsnd
->pcm
->pcm_params
);
1351 AUD_remove_card(&vsnd
->card
);
1352 qemu_mutex_destroy(&vsnd
->cmdq_mutex
);
1353 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_CONTROL
]);
1354 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_EVENT
]);
1355 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_TX
]);
1356 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_RX
]);
1357 virtio_cleanup(vdev
);
1361 static void virtio_snd_reset(VirtIODevice
*vdev
)
1363 VirtIOSound
*vsnd
= VIRTIO_SND(vdev
);
1364 virtio_snd_ctrl_command
*cmd
;
1367 * Sanity check that the invalid buffer message queue is emptied at the end
1368 * of every virtio_snd_handle_tx_xfer/virtio_snd_handle_rx_xfer call, and
1369 * must be empty otherwise.
1371 g_assert(QSIMPLEQ_EMPTY(&vsnd
->invalid
));
1373 WITH_QEMU_LOCK_GUARD(&vsnd
->cmdq_mutex
) {
1374 while (!QTAILQ_EMPTY(&vsnd
->cmdq
)) {
1375 cmd
= QTAILQ_FIRST(&vsnd
->cmdq
);
1376 QTAILQ_REMOVE(&vsnd
->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
)