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 * Copyright (c) 2023 Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org> 9 * Copyright (C) 2019 OpenSynergy GmbH 10 * 11 * This work is licensed under the terms of the GNU GPL, version 2 or 12 * (at your option) any later version. See the COPYING file in the 13 * top-level directory. 14 */ 15 16 #ifndef QEMU_VIRTIO_SOUND_H 17 #define QEMU_VIRTIO_SOUND_H 18 19 #include "hw/virtio/virtio.h" 20 #include "audio/audio.h" 21 #include "standard-headers/linux/virtio_ids.h" 22 #include "standard-headers/linux/virtio_snd.h" 23 24 #define TYPE_VIRTIO_SND "virtio-sound-device" 25 #define VIRTIO_SND(obj) \ 26 OBJECT_CHECK(VirtIOSound, (obj), TYPE_VIRTIO_SND) 27 28 /* CONFIGURATION SPACE */ 29 30 typedef struct virtio_snd_config virtio_snd_config; 31 32 /* COMMON DEFINITIONS */ 33 34 /* common header for request/response*/ 35 typedef struct virtio_snd_hdr virtio_snd_hdr; 36 37 /* event notification */ 38 typedef struct virtio_snd_event virtio_snd_event; 39 40 /* common control request to query an item information */ 41 typedef struct virtio_snd_query_info virtio_snd_query_info; 42 43 /* JACK CONTROL MESSAGES */ 44 45 typedef struct virtio_snd_jack_hdr virtio_snd_jack_hdr; 46 47 /* jack information structure */ 48 typedef struct virtio_snd_jack_info virtio_snd_jack_info; 49 50 /* jack remapping control request */ 51 typedef struct virtio_snd_jack_remap virtio_snd_jack_remap; 52 53 /* 54 * PCM CONTROL MESSAGES 55 */ 56 typedef struct virtio_snd_pcm_hdr virtio_snd_pcm_hdr; 57 58 /* PCM stream info structure */ 59 typedef struct virtio_snd_pcm_info virtio_snd_pcm_info; 60 61 /* set PCM stream params */ 62 typedef struct virtio_snd_pcm_set_params virtio_snd_pcm_set_params; 63 64 /* I/O request header */ 65 typedef struct virtio_snd_pcm_xfer virtio_snd_pcm_xfer; 66 67 /* I/O request status */ 68 typedef struct virtio_snd_pcm_status virtio_snd_pcm_status; 69 70 /* device structs */ 71 72 typedef struct VirtIOSound VirtIOSound; 73 74 typedef struct VirtIOSoundPCMStream VirtIOSoundPCMStream; 75 76 typedef struct virtio_snd_ctrl_command virtio_snd_ctrl_command; 77 78 typedef struct VirtIOSoundPCM VirtIOSoundPCM; 79 80 struct VirtIOSoundPCM { 81 VirtIOSound *snd; 82 /* 83 * PCM parameters are a separate field instead of a VirtIOSoundPCMStream 84 * field, because the operation of PCM control requests is first 85 * VIRTIO_SND_R_PCM_SET_PARAMS and then VIRTIO_SND_R_PCM_PREPARE; this 86 * means that some times we get parameters without having an allocated 87 * stream yet. 88 */ 89 virtio_snd_pcm_set_params *pcm_params; 90 VirtIOSoundPCMStream **streams; 91 }; 92 93 struct VirtIOSoundPCMStream { 94 VirtIOSoundPCM *pcm; 95 virtio_snd_pcm_info info; 96 virtio_snd_pcm_set_params params; 97 uint32_t id; 98 /* channel position values (VIRTIO_SND_CHMAP_XXX) */ 99 uint8_t positions[VIRTIO_SND_CHMAP_MAX_SIZE]; 100 VirtIOSound *s; 101 bool flushing; 102 audsettings as; 103 union { 104 SWVoiceIn *in; 105 SWVoiceOut *out; 106 } voice; 107 bool active; 108 }; 109 110 /* 111 * PCM stream state machine. 112 * ------------------------- 113 * 114 * 5.14.6.6.1 PCM Command Lifecycle 115 * ================================ 116 * 117 * A PCM stream has the following command lifecycle: 118 * - `SET PARAMETERS` 119 * The driver negotiates the stream parameters (format, transport, etc) with 120 * the device. 121 * Possible valid transitions: `SET PARAMETERS`, `PREPARE`. 122 * - `PREPARE` 123 * The device prepares the stream (allocates resources, etc). 124 * Possible valid transitions: `SET PARAMETERS`, `PREPARE`, `START`, 125 * `RELEASE`. Output only: the driver transfers data for pre-buffing. 126 * - `START` 127 * The device starts the stream (unmute, putting into running state, etc). 128 * Possible valid transitions: `STOP`. 129 * The driver transfers data to/from the stream. 130 * - `STOP` 131 * The device stops the stream (mute, putting into non-running state, etc). 132 * Possible valid transitions: `START`, `RELEASE`. 133 * - `RELEASE` 134 * The device releases the stream (frees resources, etc). 135 * Possible valid transitions: `SET PARAMETERS`, `PREPARE`. 136 * 137 * +---------------+ +---------+ +---------+ +-------+ +-------+ 138 * | SetParameters | | Prepare | | Release | | Start | | Stop | 139 * +---------------+ +---------+ +---------+ +-------+ +-------+ 140 * |- | | | | 141 * || | | | | 142 * |< | | | | 143 * |------------->| | | | 144 * |<-------------| | | | 145 * | |- | | | 146 * | || | | | 147 * | |< | | | 148 * | |--------------------->| | 149 * | |---------->| | | 150 * | | | |-------->| 151 * | | | |<--------| 152 * | | |<-------------------| 153 * |<-------------------------| | | 154 * | |<----------| | | 155 * 156 * CTRL in the VirtIOSound device 157 * ============================== 158 * 159 * The control messages that affect the state of a stream arrive in the 160 * `virtio_snd_handle_ctrl()` queue callback and are of type `struct 161 * virtio_snd_ctrl_command`. They are stored in a queue field in the device 162 * type, `VirtIOSound`. This allows deferring the CTRL request completion if 163 * it's not immediately possible due to locking/state reasons. 164 * 165 * The CTRL message is finally handled in `process_cmd()`. 166 */ 167 struct VirtIOSound { 168 VirtIODevice parent_obj; 169 170 VirtQueue *queues[VIRTIO_SND_VQ_MAX]; 171 uint64_t features; 172 VirtIOSoundPCM *pcm; 173 QEMUSoundCard card; 174 VMChangeStateEntry *vmstate; 175 virtio_snd_config snd_conf; 176 QemuMutex cmdq_mutex; 177 QTAILQ_HEAD(, virtio_snd_ctrl_command) cmdq; 178 bool processing_cmdq; 179 }; 180 181 struct virtio_snd_ctrl_command { 182 VirtQueueElement *elem; 183 VirtQueue *vq; 184 virtio_snd_hdr ctrl; 185 virtio_snd_hdr resp; 186 QTAILQ_ENTRY(virtio_snd_ctrl_command) next; 187 }; 188 #endif 189