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 "sysemu/runstate.h"
25 #include "qapi/error.h"
26 #include "hw/audio/virtio-snd.h"
28 #define VIRTIO_SOUND_VM_VERSION 1
29 #define VIRTIO_SOUND_JACK_DEFAULT 0
30 #define VIRTIO_SOUND_STREAM_DEFAULT 2
31 #define VIRTIO_SOUND_CHMAP_DEFAULT 0
32 #define VIRTIO_SOUND_HDA_FN_NID 0
34 static void virtio_snd_pcm_out_cb(void *data
, int available
);
35 static void virtio_snd_process_cmdq(VirtIOSound
*s
);
36 static void virtio_snd_pcm_flush(VirtIOSoundPCMStream
*stream
);
37 static void virtio_snd_pcm_in_cb(void *data
, int available
);
38 static void virtio_snd_unrealize(DeviceState
*dev
);
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
,
72 .minimum_version_id
= VIRTIO_SOUND_VM_VERSION
,
73 .version_id
= VIRTIO_SOUND_VM_VERSION
,
74 .fields
= (const VMStateField
[]) {
75 VMSTATE_VIRTIO_DEVICE
,
80 static Property virtio_snd_properties
[] = {
81 DEFINE_AUDIO_PROPERTIES(VirtIOSound
, card
),
82 DEFINE_PROP_UINT32("jacks", VirtIOSound
, snd_conf
.jacks
,
83 VIRTIO_SOUND_JACK_DEFAULT
),
84 DEFINE_PROP_UINT32("streams", VirtIOSound
, snd_conf
.streams
,
85 VIRTIO_SOUND_STREAM_DEFAULT
),
86 DEFINE_PROP_UINT32("chmaps", VirtIOSound
, snd_conf
.chmaps
,
87 VIRTIO_SOUND_CHMAP_DEFAULT
),
88 DEFINE_PROP_END_OF_LIST(),
92 virtio_snd_get_config(VirtIODevice
*vdev
, uint8_t *config
)
94 VirtIOSound
*s
= VIRTIO_SND(vdev
);
95 virtio_snd_config
*sndconfig
=
96 (virtio_snd_config
*)config
;
97 trace_virtio_snd_get_config(vdev
,
102 memcpy(sndconfig
, &s
->snd_conf
, sizeof(s
->snd_conf
));
103 cpu_to_le32s(&sndconfig
->jacks
);
104 cpu_to_le32s(&sndconfig
->streams
);
105 cpu_to_le32s(&sndconfig
->chmaps
);
110 virtio_snd_pcm_buffer_free(VirtIOSoundPCMBuffer
*buffer
)
112 g_free(buffer
->elem
);
117 virtio_snd_ctrl_cmd_free(virtio_snd_ctrl_command
*cmd
)
124 * Get a specific stream from the virtio sound card device.
125 * Returns NULL if @stream_id is invalid or not allocated.
127 * @s: VirtIOSound device
128 * @stream_id: stream id
130 static VirtIOSoundPCMStream
*virtio_snd_pcm_get_stream(VirtIOSound
*s
,
133 return stream_id
>= s
->snd_conf
.streams
? NULL
:
134 s
->pcm
->streams
[stream_id
];
138 * Get params for a specific stream.
140 * @s: VirtIOSound device
141 * @stream_id: stream id
143 static virtio_snd_pcm_set_params
*virtio_snd_pcm_get_params(VirtIOSound
*s
,
146 return stream_id
>= s
->snd_conf
.streams
? NULL
147 : &s
->pcm
->pcm_params
[stream_id
];
151 * Handle the VIRTIO_SND_R_PCM_INFO request.
152 * The function writes the info structs to the request element.
154 * @s: VirtIOSound device
155 * @cmd: The request command queue element from VirtIOSound cmdq field
157 static void virtio_snd_handle_pcm_info(VirtIOSound
*s
,
158 virtio_snd_ctrl_command
*cmd
)
160 uint32_t stream_id
, start_id
, count
, size
;
161 virtio_snd_pcm_info val
;
162 virtio_snd_query_info req
;
163 VirtIOSoundPCMStream
*stream
= NULL
;
164 g_autofree virtio_snd_pcm_info
*pcm_info
= NULL
;
165 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
169 sizeof(virtio_snd_query_info
));
171 if (msg_sz
!= sizeof(virtio_snd_query_info
)) {
173 * TODO: do we need to set DEVICE_NEEDS_RESET?
175 qemu_log_mask(LOG_GUEST_ERROR
,
176 "%s: virtio-snd command size incorrect %zu vs \
177 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_query_info
));
178 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
182 start_id
= le32_to_cpu(req
.start_id
);
183 count
= le32_to_cpu(req
.count
);
184 size
= le32_to_cpu(req
.size
);
186 if (iov_size(cmd
->elem
->in_sg
, cmd
->elem
->in_num
) <
187 sizeof(virtio_snd_hdr
) + size
* count
) {
189 * TODO: do we need to set DEVICE_NEEDS_RESET?
191 error_report("pcm info: buffer too small, got: %zu, needed: %zu",
192 iov_size(cmd
->elem
->in_sg
, cmd
->elem
->in_num
),
193 sizeof(virtio_snd_pcm_info
));
194 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
198 pcm_info
= g_new0(virtio_snd_pcm_info
, count
);
199 for (uint32_t i
= 0; i
< count
; i
++) {
200 stream_id
= i
+ start_id
;
201 trace_virtio_snd_handle_pcm_info(stream_id
);
202 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
204 error_report("Invalid stream id: %"PRIu32
, stream_id
);
205 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
209 val
.hdr
.hda_fn_nid
= cpu_to_le32(val
.hdr
.hda_fn_nid
);
210 val
.features
= cpu_to_le32(val
.features
);
211 val
.formats
= cpu_to_le64(val
.formats
);
212 val
.rates
= cpu_to_le64(val
.rates
);
214 * 5.14.6.6.2.1 Device Requirements: Stream Information The device MUST
215 * NOT set undefined feature, format, rate and direction values. The
216 * device MUST initialize the padding bytes to 0.
219 memset(&pcm_info
[i
].padding
, 0, 5);
222 cmd
->payload_size
= sizeof(virtio_snd_pcm_info
) * count
;
223 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
224 iov_from_buf(cmd
->elem
->in_sg
,
226 sizeof(virtio_snd_hdr
),
232 * Set the given stream params.
233 * Called by both virtio_snd_handle_pcm_set_params and during device
235 * Returns the response status code. (VIRTIO_SND_S_*).
237 * @s: VirtIOSound device
238 * @params: The PCM params as defined in the virtio specification
241 uint32_t virtio_snd_set_pcm_params(VirtIOSound
*s
,
243 virtio_snd_pcm_set_params
*params
)
245 virtio_snd_pcm_set_params
*st_params
;
247 if (stream_id
>= s
->snd_conf
.streams
|| s
->pcm
->pcm_params
== NULL
) {
249 * TODO: do we need to set DEVICE_NEEDS_RESET?
251 virtio_error(VIRTIO_DEVICE(s
), "Streams have not been initialized.\n");
252 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
255 st_params
= virtio_snd_pcm_get_params(s
, stream_id
);
257 if (params
->channels
< 1 || params
->channels
> AUDIO_MAX_CHANNELS
) {
258 error_report("Number of channels is not supported.");
259 return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
261 if (params
->format
>= sizeof(supported_formats
) * BITS_PER_BYTE
||
262 !(supported_formats
& BIT(params
->format
))) {
263 error_report("Stream format is not supported.");
264 return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
266 if (params
->rate
>= sizeof(supported_rates
) * BITS_PER_BYTE
||
267 !(supported_rates
& BIT(params
->rate
))) {
268 error_report("Stream rate is not supported.");
269 return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
272 st_params
->buffer_bytes
= le32_to_cpu(params
->buffer_bytes
);
273 st_params
->period_bytes
= le32_to_cpu(params
->period_bytes
);
274 st_params
->features
= le32_to_cpu(params
->features
);
275 /* the following are uint8_t, so there's no need to bswap the values. */
276 st_params
->channels
= params
->channels
;
277 st_params
->format
= params
->format
;
278 st_params
->rate
= params
->rate
;
280 return cpu_to_le32(VIRTIO_SND_S_OK
);
284 * Handles the VIRTIO_SND_R_PCM_SET_PARAMS request.
286 * @s: VirtIOSound device
287 * @cmd: The request command queue element from VirtIOSound cmdq field
289 static void virtio_snd_handle_pcm_set_params(VirtIOSound
*s
,
290 virtio_snd_ctrl_command
*cmd
)
292 virtio_snd_pcm_set_params req
= { 0 };
294 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
298 sizeof(virtio_snd_pcm_set_params
));
300 if (msg_sz
!= sizeof(virtio_snd_pcm_set_params
)) {
302 * TODO: do we need to set DEVICE_NEEDS_RESET?
304 qemu_log_mask(LOG_GUEST_ERROR
,
305 "%s: virtio-snd command size incorrect %zu vs \
306 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_pcm_set_params
));
307 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
310 stream_id
= le32_to_cpu(req
.hdr
.stream_id
);
311 trace_virtio_snd_handle_pcm_set_params(stream_id
);
312 cmd
->resp
.code
= virtio_snd_set_pcm_params(s
, stream_id
, &req
);
316 * Get a QEMU Audiosystem compatible format value from a VIRTIO_SND_PCM_FMT_*
318 static AudioFormat
virtio_snd_get_qemu_format(uint32_t format
)
321 case VIRTIO_SND_PCM_FMT_##FMT: \
322 return AUDIO_FORMAT_##FMT;
331 case VIRTIO_SND_PCM_FMT_FLOAT
:
332 return AUDIO_FORMAT_F32
;
334 g_assert_not_reached();
341 * Get a QEMU Audiosystem compatible frequency value from a
342 * VIRTIO_SND_PCM_RATE_*
344 static uint32_t virtio_snd_get_qemu_freq(uint32_t rate
)
347 case VIRTIO_SND_PCM_RATE_##RATE: \
366 g_assert_not_reached();
373 * Get QEMU Audiosystem compatible audsettings from virtio based pcm stream
376 static void virtio_snd_get_qemu_audsettings(audsettings
*as
,
377 virtio_snd_pcm_set_params
*params
)
379 as
->nchannels
= MIN(AUDIO_MAX_CHANNELS
, params
->channels
);
380 as
->fmt
= virtio_snd_get_qemu_format(params
->format
);
381 as
->freq
= virtio_snd_get_qemu_freq(params
->rate
);
382 as
->endianness
= 0; /* Conforming to VIRTIO 1.0: always little endian. */
386 * Close a stream and free all its resources.
388 * @stream: VirtIOSoundPCMStream *stream
390 static void virtio_snd_pcm_close(VirtIOSoundPCMStream
*stream
)
393 virtio_snd_pcm_flush(stream
);
394 if (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) {
395 AUD_close_out(&stream
->pcm
->snd
->card
, stream
->voice
.out
);
396 stream
->voice
.out
= NULL
;
397 } else if (stream
->info
.direction
== VIRTIO_SND_D_INPUT
) {
398 AUD_close_in(&stream
->pcm
->snd
->card
, stream
->voice
.in
);
399 stream
->voice
.in
= NULL
;
405 * Prepares a VirtIOSound card stream.
406 * Returns the response status code. (VIRTIO_SND_S_*).
408 * @s: VirtIOSound device
409 * @stream_id: stream id
411 static uint32_t virtio_snd_pcm_prepare(VirtIOSound
*s
, uint32_t stream_id
)
414 virtio_snd_pcm_set_params
*params
;
415 VirtIOSoundPCMStream
*stream
;
417 if (s
->pcm
->streams
== NULL
||
418 s
->pcm
->pcm_params
== NULL
||
419 stream_id
>= s
->snd_conf
.streams
) {
420 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
423 params
= virtio_snd_pcm_get_params(s
, stream_id
);
424 if (params
== NULL
) {
425 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
428 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
429 if (stream
== NULL
) {
430 stream
= g_new0(VirtIOSoundPCMStream
, 1);
431 stream
->active
= false;
432 stream
->id
= stream_id
;
433 stream
->pcm
= s
->pcm
;
435 qemu_mutex_init(&stream
->queue_mutex
);
436 QSIMPLEQ_INIT(&stream
->queue
);
439 * stream_id >= s->snd_conf.streams was checked before so this is
442 s
->pcm
->streams
[stream_id
] = stream
;
445 virtio_snd_get_qemu_audsettings(&as
, params
);
446 stream
->info
.direction
= stream_id
< s
->snd_conf
.streams
/ 2 +
447 (s
->snd_conf
.streams
& 1) ? VIRTIO_SND_D_OUTPUT
: VIRTIO_SND_D_INPUT
;
448 stream
->info
.hdr
.hda_fn_nid
= VIRTIO_SOUND_HDA_FN_NID
;
449 stream
->info
.features
= 0;
450 stream
->info
.channels_min
= 1;
451 stream
->info
.channels_max
= as
.nchannels
;
452 stream
->info
.formats
= supported_formats
;
453 stream
->info
.rates
= supported_rates
;
454 stream
->params
= *params
;
456 stream
->positions
[0] = VIRTIO_SND_CHMAP_FL
;
457 stream
->positions
[1] = VIRTIO_SND_CHMAP_FR
;
460 if (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) {
461 stream
->voice
.out
= AUD_open_out(&s
->card
,
465 virtio_snd_pcm_out_cb
,
467 AUD_set_volume_out(stream
->voice
.out
, 0, 255, 255);
469 stream
->voice
.in
= AUD_open_in(&s
->card
,
473 virtio_snd_pcm_in_cb
,
475 AUD_set_volume_in(stream
->voice
.in
, 0, 255, 255);
478 return cpu_to_le32(VIRTIO_SND_S_OK
);
481 static const char *print_code(uint32_t code
)
484 case VIRTIO_SND_R_##CODE: \
485 return "VIRTIO_SND_R_"#CODE
491 CASE(PCM_SET_PARAMS
);
498 return "invalid code";
505 * Handles VIRTIO_SND_R_PCM_PREPARE.
507 * @s: VirtIOSound device
508 * @cmd: The request command queue element from VirtIOSound cmdq field
510 static void virtio_snd_handle_pcm_prepare(VirtIOSound
*s
,
511 virtio_snd_ctrl_command
*cmd
)
514 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
516 sizeof(virtio_snd_hdr
),
520 stream_id
= le32_to_cpu(stream_id
);
521 cmd
->resp
.code
= msg_sz
== sizeof(stream_id
)
522 ? virtio_snd_pcm_prepare(s
, stream_id
)
523 : cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
527 * Handles VIRTIO_SND_R_PCM_START.
529 * @s: VirtIOSound device
530 * @cmd: The request command queue element from VirtIOSound cmdq field
531 * @start: whether to start or stop the device
533 static void virtio_snd_handle_pcm_start_stop(VirtIOSound
*s
,
534 virtio_snd_ctrl_command
*cmd
,
537 VirtIOSoundPCMStream
*stream
;
538 virtio_snd_pcm_hdr req
;
540 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
544 sizeof(virtio_snd_pcm_hdr
));
546 if (msg_sz
!= sizeof(virtio_snd_pcm_hdr
)) {
547 qemu_log_mask(LOG_GUEST_ERROR
,
548 "%s: virtio-snd command size incorrect %zu vs \
549 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_pcm_hdr
));
550 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
554 stream_id
= le32_to_cpu(req
.stream_id
);
555 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
556 trace_virtio_snd_handle_pcm_start_stop(start
? "VIRTIO_SND_R_PCM_START" :
557 "VIRTIO_SND_R_PCM_STOP", stream_id
);
559 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
561 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
562 stream
->active
= start
;
564 if (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) {
565 AUD_set_active_out(stream
->voice
.out
, start
);
567 AUD_set_active_in(stream
->voice
.in
, start
);
570 error_report("Invalid stream id: %"PRIu32
, stream_id
);
571 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
574 stream
->active
= start
;
578 * Returns the number of I/O messages that are being processed.
580 * @stream: VirtIOSoundPCMStream
582 static size_t virtio_snd_pcm_get_io_msgs_count(VirtIOSoundPCMStream
*stream
)
584 VirtIOSoundPCMBuffer
*buffer
, *next
;
587 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
588 QSIMPLEQ_FOREACH_SAFE(buffer
, &stream
->queue
, entry
, next
) {
596 * Handles VIRTIO_SND_R_PCM_RELEASE.
598 * @s: VirtIOSound device
599 * @cmd: The request command queue element from VirtIOSound cmdq field
601 static void virtio_snd_handle_pcm_release(VirtIOSound
*s
,
602 virtio_snd_ctrl_command
*cmd
)
605 VirtIOSoundPCMStream
*stream
;
606 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
608 sizeof(virtio_snd_hdr
),
612 if (msg_sz
!= sizeof(stream_id
)) {
614 * TODO: do we need to set DEVICE_NEEDS_RESET?
616 qemu_log_mask(LOG_GUEST_ERROR
,
617 "%s: virtio-snd command size incorrect %zu vs \
618 %zu\n", __func__
, msg_sz
, sizeof(stream_id
));
619 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
623 stream_id
= le32_to_cpu(stream_id
);
624 trace_virtio_snd_handle_pcm_release(stream_id
);
625 stream
= virtio_snd_pcm_get_stream(s
, stream_id
);
626 if (stream
== NULL
) {
628 * TODO: do we need to set DEVICE_NEEDS_RESET?
630 error_report("already released stream %"PRIu32
, stream_id
);
631 virtio_error(VIRTIO_DEVICE(s
),
632 "already released stream %"PRIu32
,
634 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
638 if (virtio_snd_pcm_get_io_msgs_count(stream
)) {
640 * virtio-v1.2-csd01, 5.14.6.6.5.1,
641 * Device Requirements: Stream Release
643 * - The device MUST complete all pending I/O messages for the
644 * specified stream ID.
645 * - The device MUST NOT complete the control request while there
646 * are pending I/O messages for the specified stream ID.
648 trace_virtio_snd_pcm_stream_flush(stream_id
);
649 virtio_snd_pcm_flush(stream
);
652 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
656 * The actual processing done in virtio_snd_process_cmdq().
658 * @s: VirtIOSound device
659 * @cmd: control command request
662 process_cmd(VirtIOSound
*s
, virtio_snd_ctrl_command
*cmd
)
665 size_t msg_sz
= iov_to_buf(cmd
->elem
->out_sg
,
669 sizeof(virtio_snd_hdr
));
671 if (msg_sz
!= sizeof(virtio_snd_hdr
)) {
673 * TODO: do we need to set DEVICE_NEEDS_RESET?
675 qemu_log_mask(LOG_GUEST_ERROR
,
676 "%s: virtio-snd command size incorrect %zu vs \
677 %zu\n", __func__
, msg_sz
, sizeof(virtio_snd_hdr
));
681 code
= le32_to_cpu(cmd
->ctrl
.code
);
683 trace_virtio_snd_handle_code(code
, print_code(code
));
686 case VIRTIO_SND_R_JACK_INFO
:
687 case VIRTIO_SND_R_JACK_REMAP
:
688 qemu_log_mask(LOG_UNIMP
,
689 "virtio_snd: jack functionality is unimplemented.\n");
690 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
692 case VIRTIO_SND_R_PCM_INFO
:
693 virtio_snd_handle_pcm_info(s
, cmd
);
695 case VIRTIO_SND_R_PCM_START
:
696 virtio_snd_handle_pcm_start_stop(s
, cmd
, true);
698 case VIRTIO_SND_R_PCM_STOP
:
699 virtio_snd_handle_pcm_start_stop(s
, cmd
, false);
701 case VIRTIO_SND_R_PCM_SET_PARAMS
:
702 virtio_snd_handle_pcm_set_params(s
, cmd
);
704 case VIRTIO_SND_R_PCM_PREPARE
:
705 virtio_snd_handle_pcm_prepare(s
, cmd
);
707 case VIRTIO_SND_R_PCM_RELEASE
:
708 virtio_snd_handle_pcm_release(s
, cmd
);
710 case VIRTIO_SND_R_CHMAP_INFO
:
711 qemu_log_mask(LOG_UNIMP
,
712 "virtio_snd: chmap info functionality is unimplemented.\n");
713 trace_virtio_snd_handle_chmap_info();
714 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_NOT_SUPP
);
718 error_report("virtio snd header not recognized: %"PRIu32
, code
);
719 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
722 iov_from_buf(cmd
->elem
->in_sg
,
726 sizeof(virtio_snd_hdr
));
727 virtqueue_push(cmd
->vq
, cmd
->elem
,
728 sizeof(virtio_snd_hdr
) + cmd
->payload_size
);
729 virtio_notify(VIRTIO_DEVICE(s
), cmd
->vq
);
733 * Consume all elements in command queue.
735 * @s: VirtIOSound device
737 static void virtio_snd_process_cmdq(VirtIOSound
*s
)
739 virtio_snd_ctrl_command
*cmd
;
741 if (unlikely(qatomic_read(&s
->processing_cmdq
))) {
745 WITH_QEMU_LOCK_GUARD(&s
->cmdq_mutex
) {
746 qatomic_set(&s
->processing_cmdq
, true);
747 while (!QTAILQ_EMPTY(&s
->cmdq
)) {
748 cmd
= QTAILQ_FIRST(&s
->cmdq
);
750 /* process command */
753 QTAILQ_REMOVE(&s
->cmdq
, cmd
, next
);
755 virtio_snd_ctrl_cmd_free(cmd
);
757 qatomic_set(&s
->processing_cmdq
, false);
762 * The control message handler. Pops an element from the control virtqueue,
763 * and stores them to VirtIOSound's cmdq queue and finally calls
764 * virtio_snd_process_cmdq() for processing.
766 * @vdev: VirtIOSound device
767 * @vq: Control virtqueue
769 static void virtio_snd_handle_ctrl(VirtIODevice
*vdev
, VirtQueue
*vq
)
771 VirtIOSound
*s
= VIRTIO_SND(vdev
);
772 VirtQueueElement
*elem
;
773 virtio_snd_ctrl_command
*cmd
;
775 trace_virtio_snd_handle_ctrl(vdev
, vq
);
777 if (!virtio_queue_ready(vq
)) {
781 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
783 cmd
= g_new0(virtio_snd_ctrl_command
, 1);
786 cmd
->resp
.code
= cpu_to_le32(VIRTIO_SND_S_OK
);
787 /* implicit cmd->payload_size = 0; */
788 QTAILQ_INSERT_TAIL(&s
->cmdq
, cmd
, next
);
789 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
792 virtio_snd_process_cmdq(s
);
796 * The event virtqueue handler.
797 * Not implemented yet.
799 * @vdev: VirtIOSound device
802 static void virtio_snd_handle_event(VirtIODevice
*vdev
, VirtQueue
*vq
)
804 qemu_log_mask(LOG_UNIMP
, "virtio_snd: event queue is unimplemented.\n");
805 trace_virtio_snd_handle_event();
809 * Must only be called if vsnd->invalid is not empty.
811 static inline void empty_invalid_queue(VirtIODevice
*vdev
, VirtQueue
*vq
)
813 VirtIOSoundPCMBuffer
*buffer
= NULL
;
814 virtio_snd_pcm_status resp
= { 0 };
815 VirtIOSound
*vsnd
= VIRTIO_SND(vdev
);
817 g_assert(!QSIMPLEQ_EMPTY(&vsnd
->invalid
));
819 while (!QSIMPLEQ_EMPTY(&vsnd
->invalid
)) {
820 buffer
= QSIMPLEQ_FIRST(&vsnd
->invalid
);
821 /* If buffer->vq != vq, our logic is fundamentally wrong, so bail out */
822 g_assert(buffer
->vq
== vq
);
824 resp
.status
= cpu_to_le32(VIRTIO_SND_S_BAD_MSG
);
825 iov_from_buf(buffer
->elem
->in_sg
,
826 buffer
->elem
->in_num
,
829 sizeof(virtio_snd_pcm_status
));
832 sizeof(virtio_snd_pcm_status
));
833 QSIMPLEQ_REMOVE_HEAD(&vsnd
->invalid
, entry
);
834 virtio_snd_pcm_buffer_free(buffer
);
836 /* Notify vq about virtio_snd_pcm_status responses. */
837 virtio_notify(vdev
, vq
);
841 * The tx virtqueue handler. Makes the buffers available to their respective
842 * streams for consumption.
844 * @vdev: VirtIOSound device
847 static void virtio_snd_handle_tx_xfer(VirtIODevice
*vdev
, VirtQueue
*vq
)
849 VirtIOSound
*vsnd
= VIRTIO_SND(vdev
);
850 VirtIOSoundPCMBuffer
*buffer
;
851 VirtQueueElement
*elem
;
853 virtio_snd_pcm_xfer hdr
;
856 * If any of the I/O messages are invalid, put them in vsnd->invalid and
857 * return them after the for loop.
859 bool must_empty_invalid_queue
= false;
861 if (!virtio_queue_ready(vq
)) {
864 trace_virtio_snd_handle_tx_xfer();
867 VirtIOSoundPCMStream
*stream
;
869 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
873 /* get the message hdr object */
874 msg_sz
= iov_to_buf(elem
->out_sg
,
878 sizeof(virtio_snd_pcm_xfer
));
879 if (msg_sz
!= sizeof(virtio_snd_pcm_xfer
)) {
882 stream_id
= le32_to_cpu(hdr
.stream_id
);
884 if (stream_id
>= vsnd
->snd_conf
.streams
885 || vsnd
->pcm
->streams
[stream_id
] == NULL
) {
889 stream
= vsnd
->pcm
->streams
[stream_id
];
890 if (stream
->info
.direction
!= VIRTIO_SND_D_OUTPUT
) {
894 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
895 size
= iov_size(elem
->out_sg
, elem
->out_num
) - msg_sz
;
897 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
) + size
);
899 buffer
->populated
= false;
904 QSIMPLEQ_INSERT_TAIL(&stream
->queue
, buffer
, entry
);
909 must_empty_invalid_queue
= true;
910 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
));
913 QSIMPLEQ_INSERT_TAIL(&vsnd
->invalid
, buffer
, entry
);
916 if (must_empty_invalid_queue
) {
917 empty_invalid_queue(vdev
, vq
);
922 * The rx virtqueue handler. Makes the buffers available to their respective
923 * streams for consumption.
925 * @vdev: VirtIOSound device
928 static void virtio_snd_handle_rx_xfer(VirtIODevice
*vdev
, VirtQueue
*vq
)
930 VirtIOSound
*vsnd
= VIRTIO_SND(vdev
);
931 VirtIOSoundPCMBuffer
*buffer
;
932 VirtQueueElement
*elem
;
934 virtio_snd_pcm_xfer hdr
;
937 * if any of the I/O messages are invalid, put them in vsnd->invalid and
938 * return them after the for loop.
940 bool must_empty_invalid_queue
= false;
942 if (!virtio_queue_ready(vq
)) {
945 trace_virtio_snd_handle_rx_xfer();
948 VirtIOSoundPCMStream
*stream
;
950 elem
= virtqueue_pop(vq
, sizeof(VirtQueueElement
));
954 /* get the message hdr object */
955 msg_sz
= iov_to_buf(elem
->out_sg
,
959 sizeof(virtio_snd_pcm_xfer
));
960 if (msg_sz
!= sizeof(virtio_snd_pcm_xfer
)) {
963 stream_id
= le32_to_cpu(hdr
.stream_id
);
965 if (stream_id
>= vsnd
->snd_conf
.streams
966 || !vsnd
->pcm
->streams
[stream_id
]) {
970 stream
= vsnd
->pcm
->streams
[stream_id
];
971 if (stream
== NULL
|| stream
->info
.direction
!= VIRTIO_SND_D_INPUT
) {
974 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
975 size
= iov_size(elem
->in_sg
, elem
->in_num
) -
976 sizeof(virtio_snd_pcm_status
);
977 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
) + size
);
982 QSIMPLEQ_INSERT_TAIL(&stream
->queue
, buffer
, entry
);
987 must_empty_invalid_queue
= true;
988 buffer
= g_malloc0(sizeof(VirtIOSoundPCMBuffer
));
991 QSIMPLEQ_INSERT_TAIL(&vsnd
->invalid
, buffer
, entry
);
994 if (must_empty_invalid_queue
) {
995 empty_invalid_queue(vdev
, vq
);
999 static uint64_t get_features(VirtIODevice
*vdev
, uint64_t features
,
1003 * virtio-v1.2-csd01, 5.14.3,
1005 * None currently defined.
1007 VirtIOSound
*s
= VIRTIO_SND(vdev
);
1008 features
|= s
->features
;
1010 trace_virtio_snd_get_features(vdev
, features
);
1016 virtio_snd_vm_state_change(void *opaque
, bool running
,
1020 trace_virtio_snd_vm_state_running();
1022 trace_virtio_snd_vm_state_stopped();
1026 static void virtio_snd_realize(DeviceState
*dev
, Error
**errp
)
1029 VirtIOSound
*vsnd
= VIRTIO_SND(dev
);
1030 VirtIODevice
*vdev
= VIRTIO_DEVICE(dev
);
1031 virtio_snd_pcm_set_params default_params
= { 0 };
1034 trace_virtio_snd_realize(vsnd
);
1036 /* check number of jacks and streams */
1037 if (vsnd
->snd_conf
.jacks
> 8) {
1039 "Invalid number of jacks: %"PRIu32
,
1040 vsnd
->snd_conf
.jacks
);
1043 if (vsnd
->snd_conf
.streams
< 1 || vsnd
->snd_conf
.streams
> 10) {
1045 "Invalid number of streams: %"PRIu32
,
1046 vsnd
->snd_conf
.streams
);
1050 if (vsnd
->snd_conf
.chmaps
> VIRTIO_SND_CHMAP_MAX_SIZE
) {
1052 "Invalid number of channel maps: %"PRIu32
,
1053 vsnd
->snd_conf
.chmaps
);
1057 if (!AUD_register_card("virtio-sound", &vsnd
->card
, errp
)) {
1062 qemu_add_vm_change_state_handler(virtio_snd_vm_state_change
, vsnd
);
1064 vsnd
->pcm
= g_new0(VirtIOSoundPCM
, 1);
1065 vsnd
->pcm
->snd
= vsnd
;
1066 vsnd
->pcm
->streams
=
1067 g_new0(VirtIOSoundPCMStream
*, vsnd
->snd_conf
.streams
);
1068 vsnd
->pcm
->pcm_params
=
1069 g_new0(virtio_snd_pcm_set_params
, vsnd
->snd_conf
.streams
);
1071 virtio_init(vdev
, VIRTIO_ID_SOUND
, sizeof(virtio_snd_config
));
1072 virtio_add_feature(&vsnd
->features
, VIRTIO_F_VERSION_1
);
1074 /* set default params for all streams */
1075 default_params
.features
= 0;
1076 default_params
.buffer_bytes
= cpu_to_le32(8192);
1077 default_params
.period_bytes
= cpu_to_le32(2048);
1078 default_params
.channels
= 2;
1079 default_params
.format
= VIRTIO_SND_PCM_FMT_S16
;
1080 default_params
.rate
= VIRTIO_SND_PCM_RATE_48000
;
1081 vsnd
->queues
[VIRTIO_SND_VQ_CONTROL
] =
1082 virtio_add_queue(vdev
, 64, virtio_snd_handle_ctrl
);
1083 vsnd
->queues
[VIRTIO_SND_VQ_EVENT
] =
1084 virtio_add_queue(vdev
, 64, virtio_snd_handle_event
);
1085 vsnd
->queues
[VIRTIO_SND_VQ_TX
] =
1086 virtio_add_queue(vdev
, 64, virtio_snd_handle_tx_xfer
);
1087 vsnd
->queues
[VIRTIO_SND_VQ_RX
] =
1088 virtio_add_queue(vdev
, 64, virtio_snd_handle_rx_xfer
);
1089 qemu_mutex_init(&vsnd
->cmdq_mutex
);
1090 QTAILQ_INIT(&vsnd
->cmdq
);
1091 QSIMPLEQ_INIT(&vsnd
->invalid
);
1093 for (uint32_t i
= 0; i
< vsnd
->snd_conf
.streams
; i
++) {
1094 status
= virtio_snd_set_pcm_params(vsnd
, i
, &default_params
);
1095 if (status
!= cpu_to_le32(VIRTIO_SND_S_OK
)) {
1097 "Can't initialize stream params, device responded with %s.",
1098 print_code(status
));
1101 status
= virtio_snd_pcm_prepare(vsnd
, i
);
1102 if (status
!= cpu_to_le32(VIRTIO_SND_S_OK
)) {
1104 "Can't prepare streams, device responded with %s.",
1105 print_code(status
));
1113 virtio_snd_unrealize(dev
);
1116 static inline void return_tx_buffer(VirtIOSoundPCMStream
*stream
,
1117 VirtIOSoundPCMBuffer
*buffer
)
1119 virtio_snd_pcm_status resp
= { 0 };
1120 resp
.status
= cpu_to_le32(VIRTIO_SND_S_OK
);
1121 resp
.latency_bytes
= cpu_to_le32((uint32_t)buffer
->size
);
1122 iov_from_buf(buffer
->elem
->in_sg
,
1123 buffer
->elem
->in_num
,
1126 sizeof(virtio_snd_pcm_status
));
1127 virtqueue_push(buffer
->vq
,
1129 sizeof(virtio_snd_pcm_status
));
1130 virtio_notify(VIRTIO_DEVICE(stream
->s
), buffer
->vq
);
1131 QSIMPLEQ_REMOVE(&stream
->queue
,
1133 VirtIOSoundPCMBuffer
,
1135 virtio_snd_pcm_buffer_free(buffer
);
1139 * AUD_* output callback.
1141 * @data: VirtIOSoundPCMStream stream
1142 * @available: number of bytes that can be written with AUD_write()
1144 static void virtio_snd_pcm_out_cb(void *data
, int available
)
1146 VirtIOSoundPCMStream
*stream
= data
;
1147 VirtIOSoundPCMBuffer
*buffer
;
1150 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1151 while (!QSIMPLEQ_EMPTY(&stream
->queue
)) {
1152 buffer
= QSIMPLEQ_FIRST(&stream
->queue
);
1153 if (!virtio_queue_ready(buffer
->vq
)) {
1156 if (!stream
->active
) {
1157 /* Stream has stopped, so do not perform AUD_write. */
1158 return_tx_buffer(stream
, buffer
);
1161 if (!buffer
->populated
) {
1162 iov_to_buf(buffer
->elem
->out_sg
,
1163 buffer
->elem
->out_num
,
1164 sizeof(virtio_snd_pcm_xfer
),
1167 buffer
->populated
= true;
1170 size
= AUD_write(stream
->voice
.out
,
1171 buffer
->data
+ buffer
->offset
,
1172 MIN(buffer
->size
, available
));
1173 assert(size
<= MIN(buffer
->size
, available
));
1175 /* break out of both loops */
1179 buffer
->size
-= size
;
1180 buffer
->offset
+= size
;
1182 if (buffer
->size
< 1) {
1183 return_tx_buffer(stream
, buffer
);
1198 * Flush all buffer data from this input stream's queue into the driver's
1201 * @stream: VirtIOSoundPCMStream *stream
1203 static inline void return_rx_buffer(VirtIOSoundPCMStream
*stream
,
1204 VirtIOSoundPCMBuffer
*buffer
)
1206 virtio_snd_pcm_status resp
= { 0 };
1207 resp
.status
= cpu_to_le32(VIRTIO_SND_S_OK
);
1208 resp
.latency_bytes
= 0;
1209 /* Copy data -if any- to guest */
1210 iov_from_buf(buffer
->elem
->in_sg
,
1211 buffer
->elem
->in_num
,
1215 iov_from_buf(buffer
->elem
->in_sg
,
1216 buffer
->elem
->in_num
,
1219 sizeof(virtio_snd_pcm_status
));
1220 virtqueue_push(buffer
->vq
,
1222 sizeof(virtio_snd_pcm_status
) + buffer
->size
);
1223 virtio_notify(VIRTIO_DEVICE(stream
->s
), buffer
->vq
);
1224 QSIMPLEQ_REMOVE(&stream
->queue
,
1226 VirtIOSoundPCMBuffer
,
1228 virtio_snd_pcm_buffer_free(buffer
);
1233 * AUD_* input callback.
1235 * @data: VirtIOSoundPCMStream stream
1236 * @available: number of bytes that can be read with AUD_read()
1238 static void virtio_snd_pcm_in_cb(void *data
, int available
)
1240 VirtIOSoundPCMStream
*stream
= data
;
1241 VirtIOSoundPCMBuffer
*buffer
;
1242 size_t size
, max_size
;
1244 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1245 while (!QSIMPLEQ_EMPTY(&stream
->queue
)) {
1246 buffer
= QSIMPLEQ_FIRST(&stream
->queue
);
1247 if (!virtio_queue_ready(buffer
->vq
)) {
1250 if (!stream
->active
) {
1251 /* Stream has stopped, so do not perform AUD_read. */
1252 return_rx_buffer(stream
, buffer
);
1256 max_size
= iov_size(buffer
->elem
->in_sg
, buffer
->elem
->in_num
);
1258 if (buffer
->size
>= max_size
) {
1259 return_rx_buffer(stream
, buffer
);
1262 size
= AUD_read(stream
->voice
.in
,
1263 buffer
->data
+ buffer
->size
,
1264 MIN(available
, (stream
->params
.period_bytes
-
1270 buffer
->size
+= size
;
1272 if (buffer
->size
>= stream
->params
.period_bytes
) {
1273 return_rx_buffer(stream
, buffer
);
1288 * Flush all buffer data from this output stream's queue into the driver's
1291 * @stream: VirtIOSoundPCMStream *stream
1293 static inline void virtio_snd_pcm_flush(VirtIOSoundPCMStream
*stream
)
1295 VirtIOSoundPCMBuffer
*buffer
;
1296 void (*cb
)(VirtIOSoundPCMStream
*, VirtIOSoundPCMBuffer
*) =
1297 (stream
->info
.direction
== VIRTIO_SND_D_OUTPUT
) ? return_tx_buffer
:
1300 WITH_QEMU_LOCK_GUARD(&stream
->queue_mutex
) {
1301 while (!QSIMPLEQ_EMPTY(&stream
->queue
)) {
1302 buffer
= QSIMPLEQ_FIRST(&stream
->queue
);
1308 static void virtio_snd_unrealize(DeviceState
*dev
)
1310 VirtIODevice
*vdev
= VIRTIO_DEVICE(dev
);
1311 VirtIOSound
*vsnd
= VIRTIO_SND(dev
);
1312 VirtIOSoundPCMStream
*stream
;
1314 qemu_del_vm_change_state_handler(vsnd
->vmstate
);
1315 trace_virtio_snd_unrealize(vsnd
);
1318 if (vsnd
->pcm
->streams
) {
1319 for (uint32_t i
= 0; i
< vsnd
->snd_conf
.streams
; i
++) {
1320 stream
= vsnd
->pcm
->streams
[i
];
1322 virtio_snd_process_cmdq(stream
->s
);
1323 virtio_snd_pcm_close(stream
);
1324 qemu_mutex_destroy(&stream
->queue_mutex
);
1328 g_free(vsnd
->pcm
->streams
);
1330 g_free(vsnd
->pcm
->pcm_params
);
1334 AUD_remove_card(&vsnd
->card
);
1335 qemu_mutex_destroy(&vsnd
->cmdq_mutex
);
1336 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_CONTROL
]);
1337 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_EVENT
]);
1338 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_TX
]);
1339 virtio_delete_queue(vsnd
->queues
[VIRTIO_SND_VQ_RX
]);
1340 virtio_cleanup(vdev
);
1344 static void virtio_snd_reset(VirtIODevice
*vdev
)
1346 VirtIOSound
*vsnd
= VIRTIO_SND(vdev
);
1347 virtio_snd_ctrl_command
*cmd
;
1350 * Sanity check that the invalid buffer message queue is emptied at the end
1351 * of every virtio_snd_handle_tx_xfer/virtio_snd_handle_rx_xfer call, and
1352 * must be empty otherwise.
1354 g_assert(QSIMPLEQ_EMPTY(&vsnd
->invalid
));
1356 WITH_QEMU_LOCK_GUARD(&vsnd
->cmdq_mutex
) {
1357 while (!QTAILQ_EMPTY(&vsnd
->cmdq
)) {
1358 cmd
= QTAILQ_FIRST(&vsnd
->cmdq
);
1359 QTAILQ_REMOVE(&vsnd
->cmdq
, cmd
, next
);
1360 virtio_snd_ctrl_cmd_free(cmd
);
1365 static void virtio_snd_class_init(ObjectClass
*klass
, void *data
)
1367 DeviceClass
*dc
= DEVICE_CLASS(klass
);
1368 VirtioDeviceClass
*vdc
= VIRTIO_DEVICE_CLASS(klass
);
1371 set_bit(DEVICE_CATEGORY_SOUND
, dc
->categories
);
1372 device_class_set_props(dc
, virtio_snd_properties
);
1374 dc
->vmsd
= &vmstate_virtio_snd
;
1375 vdc
->vmsd
= &vmstate_virtio_snd_device
;
1376 vdc
->realize
= virtio_snd_realize
;
1377 vdc
->unrealize
= virtio_snd_unrealize
;
1378 vdc
->get_config
= virtio_snd_get_config
;
1379 vdc
->get_features
= get_features
;
1380 vdc
->reset
= virtio_snd_reset
;
1381 vdc
->legacy_features
= 0;
1384 static const TypeInfo virtio_snd_types
[] = {
1386 .name
= TYPE_VIRTIO_SND
,
1387 .parent
= TYPE_VIRTIO_DEVICE
,
1388 .instance_size
= sizeof(VirtIOSound
),
1389 .class_init
= virtio_snd_class_init
,
1393 DEFINE_TYPES(virtio_snd_types
)