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