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