]> git.ipfire.org Git - thirdparty/qemu.git/blob - hw/audio/virtio-snd.c
virtio-snd: rewrite invalid tx/rx message handling
[thirdparty/qemu.git] / hw / audio / virtio-snd.c
1 /*
2 * VIRTIO Sound Device conforming to
3 *
4 * "Virtual I/O Device (VIRTIO) Version 1.2
5 * Committee Specification Draft 01
6 * 09 May 2022"
7 *
8 * <https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-52900014>
9 *
10 * Copyright (c) 2023 Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
11 * Copyright (C) 2019 OpenSynergy GmbH
12 *
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.
16 */
17
18 #include "qemu/osdep.h"
19 #include "qemu/iov.h"
20 #include "qemu/log.h"
21 #include "qemu/error-report.h"
22 #include "include/qemu/lockable.h"
23 #include "sysemu/runstate.h"
24 #include "trace.h"
25 #include "qapi/error.h"
26 #include "hw/audio/virtio-snd.h"
27 #include "hw/core/cpu.h"
28
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
34
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);
40
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);
48
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);
63
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,
68 };
69
70 static const VMStateDescription vmstate_virtio_snd = {
71 .name = TYPE_VIRTIO_SND,
72 .unmigratable = 1,
73 .minimum_version_id = VIRTIO_SOUND_VM_VERSION,
74 .version_id = VIRTIO_SOUND_VM_VERSION,
75 .fields = (const VMStateField[]) {
76 VMSTATE_VIRTIO_DEVICE,
77 VMSTATE_END_OF_LIST()
78 },
79 };
80
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(),
90 };
91
92 static void
93 virtio_snd_get_config(VirtIODevice *vdev, uint8_t *config)
94 {
95 VirtIOSound *s = VIRTIO_SND(vdev);
96 virtio_snd_config *sndconfig =
97 (virtio_snd_config *)config;
98 trace_virtio_snd_get_config(vdev,
99 s->snd_conf.jacks,
100 s->snd_conf.streams,
101 s->snd_conf.chmaps);
102
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);
107
108 }
109
110 static void
111 virtio_snd_set_config(VirtIODevice *vdev, const uint8_t *config)
112 {
113 VirtIOSound *s = VIRTIO_SND(vdev);
114 const virtio_snd_config *sndconfig =
115 (const virtio_snd_config *)config;
116
117
118 trace_virtio_snd_set_config(vdev,
119 s->snd_conf.jacks,
120 sndconfig->jacks,
121 s->snd_conf.streams,
122 sndconfig->streams,
123 s->snd_conf.chmaps,
124 sndconfig->chmaps);
125
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);
130
131 }
132
133 static void
134 virtio_snd_pcm_buffer_free(VirtIOSoundPCMBuffer *buffer)
135 {
136 g_free(buffer->elem);
137 g_free(buffer);
138 }
139
140 static void
141 virtio_snd_ctrl_cmd_free(virtio_snd_ctrl_command *cmd)
142 {
143 g_free(cmd->elem);
144 g_free(cmd);
145 }
146
147 /*
148 * Get a specific stream from the virtio sound card device.
149 * Returns NULL if @stream_id is invalid or not allocated.
150 *
151 * @s: VirtIOSound device
152 * @stream_id: stream id
153 */
154 static VirtIOSoundPCMStream *virtio_snd_pcm_get_stream(VirtIOSound *s,
155 uint32_t stream_id)
156 {
157 return stream_id >= s->snd_conf.streams ? NULL :
158 s->pcm->streams[stream_id];
159 }
160
161 /*
162 * Get params for a specific stream.
163 *
164 * @s: VirtIOSound device
165 * @stream_id: stream id
166 */
167 static virtio_snd_pcm_set_params *virtio_snd_pcm_get_params(VirtIOSound *s,
168 uint32_t stream_id)
169 {
170 return stream_id >= s->snd_conf.streams ? NULL
171 : &s->pcm->pcm_params[stream_id];
172 }
173
174 /*
175 * Handle the VIRTIO_SND_R_PCM_INFO request.
176 * The function writes the info structs to the request element.
177 *
178 * @s: VirtIOSound device
179 * @cmd: The request command queue element from VirtIOSound cmdq field
180 */
181 static void virtio_snd_handle_pcm_info(VirtIOSound *s,
182 virtio_snd_ctrl_command *cmd)
183 {
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,
190 cmd->elem->out_num,
191 0,
192 &req,
193 sizeof(virtio_snd_query_info));
194
195 if (msg_sz != sizeof(virtio_snd_query_info)) {
196 /*
197 * TODO: do we need to set DEVICE_NEEDS_RESET?
198 */
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);
203 return;
204 }
205
206 start_id = le32_to_cpu(req.start_id);
207 count = le32_to_cpu(req.count);
208 size = le32_to_cpu(req.size);
209
210 if (iov_size(cmd->elem->in_sg, cmd->elem->in_num) <
211 sizeof(virtio_snd_hdr) + size * count) {
212 /*
213 * TODO: do we need to set DEVICE_NEEDS_RESET?
214 */
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);
219 return;
220 }
221
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);
227 if (!stream) {
228 error_report("Invalid stream id: %"PRIu32, stream_id);
229 cmd->resp.code = cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
230 return;
231 }
232 val = stream->info;
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);
237 /*
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.
241 */
242 pcm_info[i] = val;
243 memset(&pcm_info[i].padding, 0, 5);
244 }
245
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,
249 cmd->elem->in_num,
250 sizeof(virtio_snd_hdr),
251 pcm_info,
252 cmd->payload_size);
253 }
254
255 /*
256 * Set the given stream params.
257 * Called by both virtio_snd_handle_pcm_set_params and during device
258 * initialization.
259 * Returns the response status code. (VIRTIO_SND_S_*).
260 *
261 * @s: VirtIOSound device
262 * @params: The PCM params as defined in the virtio specification
263 */
264 static
265 uint32_t virtio_snd_set_pcm_params(VirtIOSound *s,
266 uint32_t stream_id,
267 virtio_snd_pcm_set_params *params)
268 {
269 virtio_snd_pcm_set_params *st_params;
270
271 if (stream_id >= s->snd_conf.streams || s->pcm->pcm_params == NULL) {
272 /*
273 * TODO: do we need to set DEVICE_NEEDS_RESET?
274 */
275 virtio_error(VIRTIO_DEVICE(s), "Streams have not been initialized.\n");
276 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
277 }
278
279 st_params = virtio_snd_pcm_get_params(s, stream_id);
280
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);
284 }
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);
288 }
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);
292 }
293
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;
301
302 return cpu_to_le32(VIRTIO_SND_S_OK);
303 }
304
305 /*
306 * Handles the VIRTIO_SND_R_PCM_SET_PARAMS request.
307 *
308 * @s: VirtIOSound device
309 * @cmd: The request command queue element from VirtIOSound cmdq field
310 */
311 static void virtio_snd_handle_pcm_set_params(VirtIOSound *s,
312 virtio_snd_ctrl_command *cmd)
313 {
314 virtio_snd_pcm_set_params req = { 0 };
315 uint32_t stream_id;
316 size_t msg_sz = iov_to_buf(cmd->elem->out_sg,
317 cmd->elem->out_num,
318 0,
319 &req,
320 sizeof(virtio_snd_pcm_set_params));
321
322 if (msg_sz != sizeof(virtio_snd_pcm_set_params)) {
323 /*
324 * TODO: do we need to set DEVICE_NEEDS_RESET?
325 */
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);
330 return;
331 }
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);
335 }
336
337 /*
338 * Get a QEMU Audiosystem compatible format value from a VIRTIO_SND_PCM_FMT_*
339 */
340 static AudioFormat virtio_snd_get_qemu_format(uint32_t format)
341 {
342 #define CASE(FMT) \
343 case VIRTIO_SND_PCM_FMT_##FMT: \
344 return AUDIO_FORMAT_##FMT;
345
346 switch (format) {
347 CASE(U8)
348 CASE(S8)
349 CASE(U16)
350 CASE(S16)
351 CASE(U32)
352 CASE(S32)
353 case VIRTIO_SND_PCM_FMT_FLOAT:
354 return AUDIO_FORMAT_F32;
355 default:
356 g_assert_not_reached();
357 }
358
359 #undef CASE
360 }
361
362 /*
363 * Get a QEMU Audiosystem compatible frequency value from a
364 * VIRTIO_SND_PCM_RATE_*
365 */
366 static uint32_t virtio_snd_get_qemu_freq(uint32_t rate)
367 {
368 #define CASE(RATE) \
369 case VIRTIO_SND_PCM_RATE_##RATE: \
370 return RATE;
371
372 switch (rate) {
373 CASE(5512)
374 CASE(8000)
375 CASE(11025)
376 CASE(16000)
377 CASE(22050)
378 CASE(32000)
379 CASE(44100)
380 CASE(48000)
381 CASE(64000)
382 CASE(88200)
383 CASE(96000)
384 CASE(176400)
385 CASE(192000)
386 CASE(384000)
387 default:
388 g_assert_not_reached();
389 }
390
391 #undef CASE
392 }
393
394 /*
395 * Get QEMU Audiosystem compatible audsettings from virtio based pcm stream
396 * params.
397 */
398 static void virtio_snd_get_qemu_audsettings(audsettings *as,
399 virtio_snd_pcm_set_params *params)
400 {
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;
405 }
406
407 /*
408 * Close a stream and free all its resources.
409 *
410 * @stream: VirtIOSoundPCMStream *stream
411 */
412 static void virtio_snd_pcm_close(VirtIOSoundPCMStream *stream)
413 {
414 if (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;
422 }
423 }
424 }
425
426 /*
427 * Prepares a VirtIOSound card stream.
428 * Returns the response status code. (VIRTIO_SND_S_*).
429 *
430 * @s: VirtIOSound device
431 * @stream_id: stream id
432 */
433 static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
434 {
435 audsettings as;
436 virtio_snd_pcm_set_params *params;
437 VirtIOSoundPCMStream *stream;
438
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);
443 }
444
445 params = virtio_snd_pcm_get_params(s, stream_id);
446 if (params == NULL) {
447 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
448 }
449
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;
456 stream->s = s;
457 qemu_mutex_init(&stream->queue_mutex);
458 QSIMPLEQ_INIT(&stream->queue);
459
460 /*
461 * stream_id >= s->snd_conf.streams was checked before so this is
462 * in-bounds
463 */
464 s->pcm->streams[stream_id] = stream;
465 }
466
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;
477
478 stream->positions[0] = VIRTIO_SND_CHMAP_FL;
479 stream->positions[1] = VIRTIO_SND_CHMAP_FR;
480 stream->as = as;
481
482 if (stream->info.direction == VIRTIO_SND_D_OUTPUT) {
483 stream->voice.out = AUD_open_out(&s->card,
484 stream->voice.out,
485 "virtio-sound.out",
486 stream,
487 virtio_snd_pcm_out_cb,
488 &as);
489 AUD_set_volume_out(stream->voice.out, 0, 255, 255);
490 } else {
491 stream->voice.in = AUD_open_in(&s->card,
492 stream->voice.in,
493 "virtio-sound.in",
494 stream,
495 virtio_snd_pcm_in_cb,
496 &as);
497 AUD_set_volume_in(stream->voice.in, 0, 255, 255);
498 }
499
500 return cpu_to_le32(VIRTIO_SND_S_OK);
501 }
502
503 static const char *print_code(uint32_t code)
504 {
505 #define CASE(CODE) \
506 case VIRTIO_SND_R_##CODE: \
507 return "VIRTIO_SND_R_"#CODE
508
509 switch (code) {
510 CASE(JACK_INFO);
511 CASE(JACK_REMAP);
512 CASE(PCM_INFO);
513 CASE(PCM_SET_PARAMS);
514 CASE(PCM_PREPARE);
515 CASE(PCM_RELEASE);
516 CASE(PCM_START);
517 CASE(PCM_STOP);
518 CASE(CHMAP_INFO);
519 default:
520 return "invalid code";
521 }
522
523 #undef CASE
524 };
525
526 /*
527 * Handles VIRTIO_SND_R_PCM_PREPARE.
528 *
529 * @s: VirtIOSound device
530 * @cmd: The request command queue element from VirtIOSound cmdq field
531 */
532 static void virtio_snd_handle_pcm_prepare(VirtIOSound *s,
533 virtio_snd_ctrl_command *cmd)
534 {
535 uint32_t stream_id;
536 size_t msg_sz = iov_to_buf(cmd->elem->out_sg,
537 cmd->elem->out_num,
538 sizeof(virtio_snd_hdr),
539 &stream_id,
540 sizeof(stream_id));
541
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);
546 }
547
548 /*
549 * Handles VIRTIO_SND_R_PCM_START.
550 *
551 * @s: VirtIOSound device
552 * @cmd: The request command queue element from VirtIOSound cmdq field
553 * @start: whether to start or stop the device
554 */
555 static void virtio_snd_handle_pcm_start_stop(VirtIOSound *s,
556 virtio_snd_ctrl_command *cmd,
557 bool start)
558 {
559 VirtIOSoundPCMStream *stream;
560 virtio_snd_pcm_hdr req;
561 uint32_t stream_id;
562 size_t msg_sz = iov_to_buf(cmd->elem->out_sg,
563 cmd->elem->out_num,
564 0,
565 &req,
566 sizeof(virtio_snd_pcm_hdr));
567
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);
573 return;
574 }
575
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);
580
581 stream = virtio_snd_pcm_get_stream(s, stream_id);
582 if (stream) {
583 WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
584 stream->active = start;
585 }
586 if (stream->info.direction == VIRTIO_SND_D_OUTPUT) {
587 AUD_set_active_out(stream->voice.out, start);
588 } else {
589 AUD_set_active_in(stream->voice.in, start);
590 }
591 } else {
592 error_report("Invalid stream id: %"PRIu32, stream_id);
593 cmd->resp.code = cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
594 return;
595 }
596 stream->active = start;
597 }
598
599 /*
600 * Returns the number of I/O messages that are being processed.
601 *
602 * @stream: VirtIOSoundPCMStream
603 */
604 static size_t virtio_snd_pcm_get_io_msgs_count(VirtIOSoundPCMStream *stream)
605 {
606 VirtIOSoundPCMBuffer *buffer, *next;
607 size_t count = 0;
608
609 WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
610 QSIMPLEQ_FOREACH_SAFE(buffer, &stream->queue, entry, next) {
611 count += 1;
612 }
613 }
614 return count;
615 }
616
617 /*
618 * Handles VIRTIO_SND_R_PCM_RELEASE.
619 *
620 * @s: VirtIOSound device
621 * @cmd: The request command queue element from VirtIOSound cmdq field
622 */
623 static void virtio_snd_handle_pcm_release(VirtIOSound *s,
624 virtio_snd_ctrl_command *cmd)
625 {
626 uint32_t stream_id;
627 VirtIOSoundPCMStream *stream;
628 size_t msg_sz = iov_to_buf(cmd->elem->out_sg,
629 cmd->elem->out_num,
630 sizeof(virtio_snd_hdr),
631 &stream_id,
632 sizeof(stream_id));
633
634 if (msg_sz != sizeof(stream_id)) {
635 /*
636 * TODO: do we need to set DEVICE_NEEDS_RESET?
637 */
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);
642 return;
643 }
644
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) {
649 /*
650 * TODO: do we need to set DEVICE_NEEDS_RESET?
651 */
652 error_report("already released stream %"PRIu32, stream_id);
653 virtio_error(VIRTIO_DEVICE(s),
654 "already released stream %"PRIu32,
655 stream_id);
656 cmd->resp.code = cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
657 return;
658 }
659
660 if (virtio_snd_pcm_get_io_msgs_count(stream)) {
661 /*
662 * virtio-v1.2-csd01, 5.14.6.6.5.1,
663 * Device Requirements: Stream Release
664 *
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.
669 */
670 trace_virtio_snd_pcm_stream_flush(stream_id);
671 virtio_snd_pcm_flush(stream);
672 }
673
674 cmd->resp.code = cpu_to_le32(VIRTIO_SND_S_OK);
675 }
676
677 /*
678 * The actual processing done in virtio_snd_process_cmdq().
679 *
680 * @s: VirtIOSound device
681 * @cmd: control command request
682 */
683 static inline void
684 process_cmd(VirtIOSound *s, virtio_snd_ctrl_command *cmd)
685 {
686 uint32_t code;
687 size_t msg_sz = iov_to_buf(cmd->elem->out_sg,
688 cmd->elem->out_num,
689 0,
690 &cmd->ctrl,
691 sizeof(virtio_snd_hdr));
692
693 if (msg_sz != sizeof(virtio_snd_hdr)) {
694 /*
695 * TODO: do we need to set DEVICE_NEEDS_RESET?
696 */
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));
700 return;
701 }
702
703 code = le32_to_cpu(cmd->ctrl.code);
704
705 trace_virtio_snd_handle_code(code, print_code(code));
706
707 switch (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);
713 break;
714 case VIRTIO_SND_R_PCM_INFO:
715 virtio_snd_handle_pcm_info(s, cmd);
716 break;
717 case VIRTIO_SND_R_PCM_START:
718 virtio_snd_handle_pcm_start_stop(s, cmd, true);
719 break;
720 case VIRTIO_SND_R_PCM_STOP:
721 virtio_snd_handle_pcm_start_stop(s, cmd, false);
722 break;
723 case VIRTIO_SND_R_PCM_SET_PARAMS:
724 virtio_snd_handle_pcm_set_params(s, cmd);
725 break;
726 case VIRTIO_SND_R_PCM_PREPARE:
727 virtio_snd_handle_pcm_prepare(s, cmd);
728 break;
729 case VIRTIO_SND_R_PCM_RELEASE:
730 virtio_snd_handle_pcm_release(s, cmd);
731 break;
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);
737 break;
738 default:
739 /* error */
740 error_report("virtio snd header not recognized: %"PRIu32, code);
741 cmd->resp.code = cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
742 }
743
744 iov_from_buf(cmd->elem->in_sg,
745 cmd->elem->in_num,
746 0,
747 &cmd->resp,
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);
752 }
753
754 /*
755 * Consume all elements in command queue.
756 *
757 * @s: VirtIOSound device
758 */
759 static void virtio_snd_process_cmdq(VirtIOSound *s)
760 {
761 virtio_snd_ctrl_command *cmd;
762
763 if (unlikely(qatomic_read(&s->processing_cmdq))) {
764 return;
765 }
766
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);
771
772 /* process command */
773 process_cmd(s, cmd);
774
775 QTAILQ_REMOVE(&s->cmdq, cmd, next);
776
777 virtio_snd_ctrl_cmd_free(cmd);
778 }
779 qatomic_set(&s->processing_cmdq, false);
780 }
781 }
782
783 /*
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.
787 *
788 * @vdev: VirtIOSound device
789 * @vq: Control virtqueue
790 */
791 static void virtio_snd_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
792 {
793 VirtIOSound *s = VIRTIO_SND(vdev);
794 VirtQueueElement *elem;
795 virtio_snd_ctrl_command *cmd;
796
797 trace_virtio_snd_handle_ctrl(vdev, vq);
798
799 if (!virtio_queue_ready(vq)) {
800 return;
801 }
802
803 elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
804 while (elem) {
805 cmd = g_new0(virtio_snd_ctrl_command, 1);
806 cmd->elem = elem;
807 cmd->vq = vq;
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));
812 }
813
814 virtio_snd_process_cmdq(s);
815 }
816
817 /*
818 * The event virtqueue handler.
819 * Not implemented yet.
820 *
821 * @vdev: VirtIOSound device
822 * @vq: event vq
823 */
824 static void virtio_snd_handle_event(VirtIODevice *vdev, VirtQueue *vq)
825 {
826 qemu_log_mask(LOG_UNIMP, "virtio_snd: event queue is unimplemented.\n");
827 trace_virtio_snd_handle_event();
828 }
829
830 /*
831 * Must only be called if vsnd->invalid is not empty.
832 */
833 static inline void empty_invalid_queue(VirtIODevice *vdev, VirtQueue *vq)
834 {
835 VirtIOSoundPCMBuffer *buffer = NULL;
836 virtio_snd_pcm_status resp = { 0 };
837 VirtIOSound *vsnd = VIRTIO_SND(vdev);
838
839 g_assert(!QSIMPLEQ_EMPTY(&vsnd->invalid));
840
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);
845
846 resp.status = cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
847 iov_from_buf(buffer->elem->in_sg,
848 buffer->elem->in_num,
849 0,
850 &resp,
851 sizeof(virtio_snd_pcm_status));
852 virtqueue_push(vq,
853 buffer->elem,
854 sizeof(virtio_snd_pcm_status));
855 QSIMPLEQ_REMOVE_HEAD(&vsnd->invalid, entry);
856 virtio_snd_pcm_buffer_free(buffer);
857 }
858 /* Notify vq about virtio_snd_pcm_status responses. */
859 virtio_notify(vdev, vq);
860 }
861
862 /*
863 * The tx virtqueue handler. Makes the buffers available to their respective
864 * streams for consumption.
865 *
866 * @vdev: VirtIOSound device
867 * @vq: tx virtqueue
868 */
869 static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
870 {
871 VirtIOSound *vsnd = VIRTIO_SND(vdev);
872 VirtIOSoundPCMBuffer *buffer;
873 VirtQueueElement *elem;
874 size_t msg_sz, size;
875 virtio_snd_pcm_xfer hdr;
876 uint32_t stream_id;
877 /*
878 * If any of the I/O messages are invalid, put them in vsnd->invalid and
879 * return them after the for loop.
880 */
881 bool must_empty_invalid_queue = false;
882
883 if (!virtio_queue_ready(vq)) {
884 return;
885 }
886 trace_virtio_snd_handle_tx_xfer();
887
888 for (VirtIOSoundPCMStream *stream = NULL;; stream = NULL) {
889 elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
890 if (!elem) {
891 break;
892 }
893 /* get the message hdr object */
894 msg_sz = iov_to_buf(elem->out_sg,
895 elem->out_num,
896 0,
897 &hdr,
898 sizeof(virtio_snd_pcm_xfer));
899 if (msg_sz != sizeof(virtio_snd_pcm_xfer)) {
900 goto tx_err;
901 }
902 stream_id = le32_to_cpu(hdr.stream_id);
903
904 if (stream_id >= vsnd->snd_conf.streams
905 || vsnd->pcm->streams[stream_id] == NULL) {
906 goto tx_err;
907 }
908
909 stream = vsnd->pcm->streams[stream_id];
910 if (stream->info.direction != VIRTIO_SND_D_OUTPUT) {
911 goto tx_err;
912 }
913
914 WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
915 size = iov_size(elem->out_sg, elem->out_num) - msg_sz;
916
917 buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer) + size);
918 buffer->elem = elem;
919 buffer->populated = false;
920 buffer->vq = vq;
921 buffer->size = size;
922 buffer->offset = 0;
923
924 QSIMPLEQ_INSERT_TAIL(&stream->queue, buffer, entry);
925 }
926 continue;
927
928 tx_err:
929 must_empty_invalid_queue = true;
930 buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer));
931 buffer->elem = elem;
932 buffer->vq = vq;
933 QSIMPLEQ_INSERT_TAIL(&vsnd->invalid, buffer, entry);
934 }
935
936 if (must_empty_invalid_queue) {
937 empty_invalid_queue(vdev, vq);
938 }
939 }
940
941 /*
942 * The rx virtqueue handler. Makes the buffers available to their respective
943 * streams for consumption.
944 *
945 * @vdev: VirtIOSound device
946 * @vq: rx virtqueue
947 */
948 static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
949 {
950 VirtIOSound *vsnd = VIRTIO_SND(vdev);
951 VirtIOSoundPCMBuffer *buffer;
952 VirtQueueElement *elem;
953 size_t msg_sz, size;
954 virtio_snd_pcm_xfer hdr;
955 uint32_t stream_id;
956 /*
957 * if any of the I/O messages are invalid, put them in vsnd->invalid and
958 * return them after the for loop.
959 */
960 bool must_empty_invalid_queue = false;
961
962 if (!virtio_queue_ready(vq)) {
963 return;
964 }
965 trace_virtio_snd_handle_rx_xfer();
966
967 for (VirtIOSoundPCMStream *stream = NULL;; stream = NULL) {
968 elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
969 if (!elem) {
970 break;
971 }
972 /* get the message hdr object */
973 msg_sz = iov_to_buf(elem->out_sg,
974 elem->out_num,
975 0,
976 &hdr,
977 sizeof(virtio_snd_pcm_xfer));
978 if (msg_sz != sizeof(virtio_snd_pcm_xfer)) {
979 goto rx_err;
980 }
981 stream_id = le32_to_cpu(hdr.stream_id);
982
983 if (stream_id >= vsnd->snd_conf.streams
984 || !vsnd->pcm->streams[stream_id]) {
985 goto rx_err;
986 }
987
988 stream = vsnd->pcm->streams[stream_id];
989 if (stream == NULL || stream->info.direction != VIRTIO_SND_D_INPUT) {
990 goto rx_err;
991 }
992 WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
993 size = iov_size(elem->in_sg, elem->in_num) -
994 sizeof(virtio_snd_pcm_status);
995 buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer) + size);
996 buffer->elem = elem;
997 buffer->vq = vq;
998 buffer->size = 0;
999 buffer->offset = 0;
1000 QSIMPLEQ_INSERT_TAIL(&stream->queue, buffer, entry);
1001 }
1002 continue;
1003
1004 rx_err:
1005 must_empty_invalid_queue = true;
1006 buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer));
1007 buffer->elem = elem;
1008 buffer->vq = vq;
1009 QSIMPLEQ_INSERT_TAIL(&vsnd->invalid, buffer, entry);
1010 }
1011
1012 if (must_empty_invalid_queue) {
1013 empty_invalid_queue(vdev, vq);
1014 }
1015 }
1016
1017 static uint64_t get_features(VirtIODevice *vdev, uint64_t features,
1018 Error **errp)
1019 {
1020 /*
1021 * virtio-v1.2-csd01, 5.14.3,
1022 * Feature Bits
1023 * None currently defined.
1024 */
1025 VirtIOSound *s = VIRTIO_SND(vdev);
1026 features |= s->features;
1027
1028 trace_virtio_snd_get_features(vdev, features);
1029
1030 return features;
1031 }
1032
1033 static void
1034 virtio_snd_vm_state_change(void *opaque, bool running,
1035 RunState state)
1036 {
1037 if (running) {
1038 trace_virtio_snd_vm_state_running();
1039 } else {
1040 trace_virtio_snd_vm_state_stopped();
1041 }
1042 }
1043
1044 static void virtio_snd_realize(DeviceState *dev, Error **errp)
1045 {
1046 ERRP_GUARD();
1047 VirtIOSound *vsnd = VIRTIO_SND(dev);
1048 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
1049 virtio_snd_pcm_set_params default_params = { 0 };
1050 uint32_t status;
1051
1052 trace_virtio_snd_realize(vsnd);
1053
1054 /* check number of jacks and streams */
1055 if (vsnd->snd_conf.jacks > 8) {
1056 error_setg(errp,
1057 "Invalid number of jacks: %"PRIu32,
1058 vsnd->snd_conf.jacks);
1059 return;
1060 }
1061 if (vsnd->snd_conf.streams < 1 || vsnd->snd_conf.streams > 10) {
1062 error_setg(errp,
1063 "Invalid number of streams: %"PRIu32,
1064 vsnd->snd_conf.streams);
1065 return;
1066 }
1067
1068 if (vsnd->snd_conf.chmaps > VIRTIO_SND_CHMAP_MAX_SIZE) {
1069 error_setg(errp,
1070 "Invalid number of channel maps: %"PRIu32,
1071 vsnd->snd_conf.chmaps);
1072 return;
1073 }
1074
1075 if (!AUD_register_card("virtio-sound", &vsnd->card, errp)) {
1076 return;
1077 }
1078
1079 vsnd->vmstate =
1080 qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd);
1081
1082 vsnd->pcm = g_new0(VirtIOSoundPCM, 1);
1083 vsnd->pcm->snd = vsnd;
1084 vsnd->pcm->streams =
1085 g_new0(VirtIOSoundPCMStream *, vsnd->snd_conf.streams);
1086 vsnd->pcm->pcm_params =
1087 g_new0(virtio_snd_pcm_set_params, vsnd->snd_conf.streams);
1088
1089 virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config));
1090 virtio_add_feature(&vsnd->features, VIRTIO_F_VERSION_1);
1091
1092 /* set default params for all streams */
1093 default_params.features = 0;
1094 default_params.buffer_bytes = cpu_to_le32(8192);
1095 default_params.period_bytes = cpu_to_le32(2048);
1096 default_params.channels = 2;
1097 default_params.format = VIRTIO_SND_PCM_FMT_S16;
1098 default_params.rate = VIRTIO_SND_PCM_RATE_48000;
1099 vsnd->queues[VIRTIO_SND_VQ_CONTROL] =
1100 virtio_add_queue(vdev, 64, virtio_snd_handle_ctrl);
1101 vsnd->queues[VIRTIO_SND_VQ_EVENT] =
1102 virtio_add_queue(vdev, 64, virtio_snd_handle_event);
1103 vsnd->queues[VIRTIO_SND_VQ_TX] =
1104 virtio_add_queue(vdev, 64, virtio_snd_handle_tx_xfer);
1105 vsnd->queues[VIRTIO_SND_VQ_RX] =
1106 virtio_add_queue(vdev, 64, virtio_snd_handle_rx_xfer);
1107 qemu_mutex_init(&vsnd->cmdq_mutex);
1108 QTAILQ_INIT(&vsnd->cmdq);
1109 QSIMPLEQ_INIT(&vsnd->invalid);
1110
1111 for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
1112 status = virtio_snd_set_pcm_params(vsnd, i, &default_params);
1113 if (status != cpu_to_le32(VIRTIO_SND_S_OK)) {
1114 error_setg(errp,
1115 "Can't initialize stream params, device responded with %s.",
1116 print_code(status));
1117 goto error_cleanup;
1118 }
1119 status = virtio_snd_pcm_prepare(vsnd, i);
1120 if (status != cpu_to_le32(VIRTIO_SND_S_OK)) {
1121 error_setg(errp,
1122 "Can't prepare streams, device responded with %s.",
1123 print_code(status));
1124 goto error_cleanup;
1125 }
1126 }
1127
1128 return;
1129
1130 error_cleanup:
1131 virtio_snd_unrealize(dev);
1132 }
1133
1134 static inline void return_tx_buffer(VirtIOSoundPCMStream *stream,
1135 VirtIOSoundPCMBuffer *buffer)
1136 {
1137 virtio_snd_pcm_status resp = { 0 };
1138 resp.status = cpu_to_le32(VIRTIO_SND_S_OK);
1139 resp.latency_bytes = cpu_to_le32((uint32_t)buffer->size);
1140 iov_from_buf(buffer->elem->in_sg,
1141 buffer->elem->in_num,
1142 0,
1143 &resp,
1144 sizeof(virtio_snd_pcm_status));
1145 virtqueue_push(buffer->vq,
1146 buffer->elem,
1147 sizeof(virtio_snd_pcm_status));
1148 virtio_notify(VIRTIO_DEVICE(stream->s), buffer->vq);
1149 QSIMPLEQ_REMOVE(&stream->queue,
1150 buffer,
1151 VirtIOSoundPCMBuffer,
1152 entry);
1153 virtio_snd_pcm_buffer_free(buffer);
1154 }
1155
1156 /*
1157 * AUD_* output callback.
1158 *
1159 * @data: VirtIOSoundPCMStream stream
1160 * @available: number of bytes that can be written with AUD_write()
1161 */
1162 static void virtio_snd_pcm_out_cb(void *data, int available)
1163 {
1164 VirtIOSoundPCMStream *stream = data;
1165 VirtIOSoundPCMBuffer *buffer;
1166 size_t size;
1167
1168 WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
1169 while (!QSIMPLEQ_EMPTY(&stream->queue)) {
1170 buffer = QSIMPLEQ_FIRST(&stream->queue);
1171 if (!virtio_queue_ready(buffer->vq)) {
1172 return;
1173 }
1174 if (!stream->active) {
1175 /* Stream has stopped, so do not perform AUD_write. */
1176 return_tx_buffer(stream, buffer);
1177 continue;
1178 }
1179 if (!buffer->populated) {
1180 iov_to_buf(buffer->elem->out_sg,
1181 buffer->elem->out_num,
1182 sizeof(virtio_snd_pcm_xfer),
1183 buffer->data,
1184 buffer->size);
1185 buffer->populated = true;
1186 }
1187 for (;;) {
1188 size = AUD_write(stream->voice.out,
1189 buffer->data + buffer->offset,
1190 MIN(buffer->size, available));
1191 assert(size <= MIN(buffer->size, available));
1192 if (size == 0) {
1193 /* break out of both loops */
1194 available = 0;
1195 break;
1196 }
1197 buffer->size -= size;
1198 buffer->offset += size;
1199 available -= size;
1200 if (buffer->size < 1) {
1201 return_tx_buffer(stream, buffer);
1202 break;
1203 }
1204 if (!available) {
1205 break;
1206 }
1207 }
1208 if (!available) {
1209 break;
1210 }
1211 }
1212 }
1213 }
1214
1215 /*
1216 * Flush all buffer data from this input stream's queue into the driver's
1217 * virtual queue.
1218 *
1219 * @stream: VirtIOSoundPCMStream *stream
1220 */
1221 static inline void return_rx_buffer(VirtIOSoundPCMStream *stream,
1222 VirtIOSoundPCMBuffer *buffer)
1223 {
1224 virtio_snd_pcm_status resp = { 0 };
1225 resp.status = cpu_to_le32(VIRTIO_SND_S_OK);
1226 resp.latency_bytes = 0;
1227 /* Copy data -if any- to guest */
1228 iov_from_buf(buffer->elem->in_sg,
1229 buffer->elem->in_num,
1230 0,
1231 buffer->data,
1232 buffer->size);
1233 iov_from_buf(buffer->elem->in_sg,
1234 buffer->elem->in_num,
1235 buffer->size,
1236 &resp,
1237 sizeof(virtio_snd_pcm_status));
1238 virtqueue_push(buffer->vq,
1239 buffer->elem,
1240 sizeof(virtio_snd_pcm_status) + buffer->size);
1241 virtio_notify(VIRTIO_DEVICE(stream->s), buffer->vq);
1242 QSIMPLEQ_REMOVE(&stream->queue,
1243 buffer,
1244 VirtIOSoundPCMBuffer,
1245 entry);
1246 virtio_snd_pcm_buffer_free(buffer);
1247 }
1248
1249
1250 /*
1251 * AUD_* input callback.
1252 *
1253 * @data: VirtIOSoundPCMStream stream
1254 * @available: number of bytes that can be read with AUD_read()
1255 */
1256 static void virtio_snd_pcm_in_cb(void *data, int available)
1257 {
1258 VirtIOSoundPCMStream *stream = data;
1259 VirtIOSoundPCMBuffer *buffer;
1260 size_t size;
1261
1262 WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
1263 while (!QSIMPLEQ_EMPTY(&stream->queue)) {
1264 buffer = QSIMPLEQ_FIRST(&stream->queue);
1265 if (!virtio_queue_ready(buffer->vq)) {
1266 return;
1267 }
1268 if (!stream->active) {
1269 /* Stream has stopped, so do not perform AUD_read. */
1270 return_rx_buffer(stream, buffer);
1271 continue;
1272 }
1273
1274 for (;;) {
1275 size = AUD_read(stream->voice.in,
1276 buffer->data + buffer->size,
1277 MIN(available, (stream->params.period_bytes -
1278 buffer->size)));
1279 if (!size) {
1280 available = 0;
1281 break;
1282 }
1283 buffer->size += size;
1284 available -= size;
1285 if (buffer->size >= stream->params.period_bytes) {
1286 return_rx_buffer(stream, buffer);
1287 break;
1288 }
1289 if (!available) {
1290 break;
1291 }
1292 }
1293 if (!available) {
1294 break;
1295 }
1296 }
1297 }
1298 }
1299
1300 /*
1301 * Flush all buffer data from this output stream's queue into the driver's
1302 * virtual queue.
1303 *
1304 * @stream: VirtIOSoundPCMStream *stream
1305 */
1306 static inline void virtio_snd_pcm_flush(VirtIOSoundPCMStream *stream)
1307 {
1308 VirtIOSoundPCMBuffer *buffer;
1309 void (*cb)(VirtIOSoundPCMStream *, VirtIOSoundPCMBuffer *) =
1310 (stream->info.direction == VIRTIO_SND_D_OUTPUT) ? return_tx_buffer :
1311 return_rx_buffer;
1312
1313 WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
1314 while (!QSIMPLEQ_EMPTY(&stream->queue)) {
1315 buffer = QSIMPLEQ_FIRST(&stream->queue);
1316 cb(stream, buffer);
1317 }
1318 }
1319 }
1320
1321 static void virtio_snd_unrealize(DeviceState *dev)
1322 {
1323 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
1324 VirtIOSound *vsnd = VIRTIO_SND(dev);
1325 VirtIOSoundPCMStream *stream;
1326
1327 qemu_del_vm_change_state_handler(vsnd->vmstate);
1328 trace_virtio_snd_unrealize(vsnd);
1329
1330 if (vsnd->pcm) {
1331 if (vsnd->pcm->streams) {
1332 for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
1333 stream = vsnd->pcm->streams[i];
1334 if (stream) {
1335 virtio_snd_process_cmdq(stream->s);
1336 virtio_snd_pcm_close(stream);
1337 qemu_mutex_destroy(&stream->queue_mutex);
1338 g_free(stream);
1339 }
1340 }
1341 g_free(vsnd->pcm->streams);
1342 }
1343 g_free(vsnd->pcm->pcm_params);
1344 g_free(vsnd->pcm);
1345 vsnd->pcm = NULL;
1346 }
1347 AUD_remove_card(&vsnd->card);
1348 qemu_mutex_destroy(&vsnd->cmdq_mutex);
1349 virtio_delete_queue(vsnd->queues[VIRTIO_SND_VQ_CONTROL]);
1350 virtio_delete_queue(vsnd->queues[VIRTIO_SND_VQ_EVENT]);
1351 virtio_delete_queue(vsnd->queues[VIRTIO_SND_VQ_TX]);
1352 virtio_delete_queue(vsnd->queues[VIRTIO_SND_VQ_RX]);
1353 virtio_cleanup(vdev);
1354 }
1355
1356
1357 static void virtio_snd_reset(VirtIODevice *vdev)
1358 {
1359 VirtIOSound *vsnd = VIRTIO_SND(vdev);
1360 virtio_snd_ctrl_command *cmd;
1361
1362 /*
1363 * Sanity check that the invalid buffer message queue is emptied at the end
1364 * of every virtio_snd_handle_tx_xfer/virtio_snd_handle_rx_xfer call, and
1365 * must be empty otherwise.
1366 */
1367 g_assert(QSIMPLEQ_EMPTY(&vsnd->invalid));
1368
1369 WITH_QEMU_LOCK_GUARD(&vsnd->cmdq_mutex) {
1370 while (!QTAILQ_EMPTY(&vsnd->cmdq)) {
1371 cmd = QTAILQ_FIRST(&vsnd->cmdq);
1372 QTAILQ_REMOVE(&vsnd->cmdq, cmd, next);
1373 virtio_snd_ctrl_cmd_free(cmd);
1374 }
1375 }
1376 }
1377
1378 static void virtio_snd_class_init(ObjectClass *klass, void *data)
1379 {
1380 DeviceClass *dc = DEVICE_CLASS(klass);
1381 VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
1382
1383
1384 set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
1385 device_class_set_props(dc, virtio_snd_properties);
1386
1387 dc->vmsd = &vmstate_virtio_snd;
1388 vdc->vmsd = &vmstate_virtio_snd_device;
1389 vdc->realize = virtio_snd_realize;
1390 vdc->unrealize = virtio_snd_unrealize;
1391 vdc->get_config = virtio_snd_get_config;
1392 vdc->set_config = virtio_snd_set_config;
1393 vdc->get_features = get_features;
1394 vdc->reset = virtio_snd_reset;
1395 vdc->legacy_features = 0;
1396 }
1397
1398 static const TypeInfo virtio_snd_types[] = {
1399 {
1400 .name = TYPE_VIRTIO_SND,
1401 .parent = TYPE_VIRTIO_DEVICE,
1402 .instance_size = sizeof(VirtIOSound),
1403 .class_init = virtio_snd_class_init,
1404 }
1405 };
1406
1407 DEFINE_TYPES(virtio_snd_types)