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