diff options
author | Manos Pitsidianakis <manos.pitsidianakis@linaro.org> | 2023-10-23 15:03:20 +0300 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2023-11-07 03:39:10 -0500 |
commit | eb9ad377bb94d2d98d18cfccc431a028361385c6 (patch) | |
tree | 8fef08b3ae5b554120eb50df9054be685f32c01c /include/hw/audio | |
parent | 2426908590c1d8d9ffb741c5552ad45d9d3ba9f8 (diff) |
virtio-sound: handle control messages and streams
Receive guest requests in the control (CTRL) queue of the virtio sound
device and reply with a NOT SUPPORTED error to all control commands.
The receiving handler is virtio_snd_handle_ctrl(). It stores all control
messages in the queue in the device's command queue. Then it calls
virtio_snd_process_cmdq() to handle each message.
The handler is process_cmd() which replies with VIRTIO_SND_S_NOT_SUPP.
Based-on: https://github.com/OpenSynergy/qemu/commit/5a2f350eec5d157b90d9c7b40a8e603f4da92471
Signed-off-by: Igor Skalkin <Igor.Skalkin@opensynergy.com>
Signed-off-by: Anton Yakovlev <Anton.Yakovlev@opensynergy.com>
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <3224aff87e7c4f2777bfe1bbbbca93b72525992c.1698062525.git.manos.pitsidianakis@linaro.org>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'include/hw/audio')
-rw-r--r-- | include/hw/audio/virtio-snd.h | 113 |
1 files changed, 111 insertions, 2 deletions
diff --git a/include/hw/audio/virtio-snd.h b/include/hw/audio/virtio-snd.h index d08065941c..cc14c875ed 100644 --- a/include/hw/audio/virtio-snd.h +++ b/include/hw/audio/virtio-snd.h @@ -67,13 +67,122 @@ typedef struct virtio_snd_pcm_xfer virtio_snd_pcm_xfer; /* I/O request status */ typedef struct virtio_snd_pcm_status virtio_snd_pcm_status; -typedef struct VirtIOSound { +/* device structs */ + +typedef struct VirtIOSound VirtIOSound; + +typedef struct VirtIOSoundPCMStream VirtIOSoundPCMStream; + +typedef struct virtio_snd_ctrl_command virtio_snd_ctrl_command; + +typedef struct VirtIOSoundPCM VirtIOSoundPCM; + +struct VirtIOSoundPCM { + VirtIOSound *snd; + /* + * PCM parameters are a separate field instead of a VirtIOSoundPCMStream + * field, because the operation of PCM control requests is first + * VIRTIO_SND_R_PCM_SET_PARAMS and then VIRTIO_SND_R_PCM_PREPARE; this + * means that some times we get parameters without having an allocated + * stream yet. + */ + virtio_snd_pcm_set_params *pcm_params; + VirtIOSoundPCMStream **streams; +}; + +struct VirtIOSoundPCMStream { + VirtIOSoundPCM *pcm; + virtio_snd_pcm_info info; + virtio_snd_pcm_set_params params; + uint32_t id; + /* channel position values (VIRTIO_SND_CHMAP_XXX) */ + uint8_t positions[VIRTIO_SND_CHMAP_MAX_SIZE]; + VirtIOSound *s; + bool flushing; + audsettings as; + union { + SWVoiceIn *in; + SWVoiceOut *out; + } voice; + bool active; +}; + +/* + * PCM stream state machine. + * ------------------------- + * + * 5.14.6.6.1 PCM Command Lifecycle + * ================================ + * + * A PCM stream has the following command lifecycle: + * - `SET PARAMETERS` + * The driver negotiates the stream parameters (format, transport, etc) with + * the device. + * Possible valid transitions: `SET PARAMETERS`, `PREPARE`. + * - `PREPARE` + * The device prepares the stream (allocates resources, etc). + * Possible valid transitions: `SET PARAMETERS`, `PREPARE`, `START`, + * `RELEASE`. Output only: the driver transfers data for pre-buffing. + * - `START` + * The device starts the stream (unmute, putting into running state, etc). + * Possible valid transitions: `STOP`. + * The driver transfers data to/from the stream. + * - `STOP` + * The device stops the stream (mute, putting into non-running state, etc). + * Possible valid transitions: `START`, `RELEASE`. + * - `RELEASE` + * The device releases the stream (frees resources, etc). + * Possible valid transitions: `SET PARAMETERS`, `PREPARE`. + * + * +---------------+ +---------+ +---------+ +-------+ +-------+ + * | SetParameters | | Prepare | | Release | | Start | | Stop | + * +---------------+ +---------+ +---------+ +-------+ +-------+ + * |- | | | | + * || | | | | + * |< | | | | + * |------------->| | | | + * |<-------------| | | | + * | |- | | | + * | || | | | + * | |< | | | + * | |--------------------->| | + * | |---------->| | | + * | | | |-------->| + * | | | |<--------| + * | | |<-------------------| + * |<-------------------------| | | + * | |<----------| | | + * + * CTRL in the VirtIOSound device + * ============================== + * + * The control messages that affect the state of a stream arrive in the + * `virtio_snd_handle_ctrl()` queue callback and are of type `struct + * virtio_snd_ctrl_command`. They are stored in a queue field in the device + * type, `VirtIOSound`. This allows deferring the CTRL request completion if + * it's not immediately possible due to locking/state reasons. + * + * The CTRL message is finally handled in `process_cmd()`. + */ +struct VirtIOSound { VirtIODevice parent_obj; VirtQueue *queues[VIRTIO_SND_VQ_MAX]; uint64_t features; + VirtIOSoundPCM *pcm; QEMUSoundCard card; VMChangeStateEntry *vmstate; virtio_snd_config snd_conf; -} VirtIOSound; + QemuMutex cmdq_mutex; + QTAILQ_HEAD(, virtio_snd_ctrl_command) cmdq; + bool processing_cmdq; +}; + +struct virtio_snd_ctrl_command { + VirtQueueElement *elem; + VirtQueue *vq; + virtio_snd_hdr ctrl; + virtio_snd_hdr resp; + QTAILQ_ENTRY(virtio_snd_ctrl_command) next; +}; #endif |