![]() |
|
|||
0001 /* SPDX-License-Identifier: MIT */ 0002 /****************************************************************************** 0003 * sndif.h 0004 * 0005 * Unified sound-device I/O interface for Xen guest OSes. 0006 * 0007 * Copyright (C) 2013-2015 GlobalLogic Inc. 0008 * Copyright (C) 2016-2017 EPAM Systems Inc. 0009 * 0010 * Authors: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 0011 * Oleksandr Grytsov <oleksandr_grytsov@epam.com> 0012 * Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com> 0013 * Iurii Konovalenko <iurii.konovalenko@globallogic.com> 0014 */ 0015 0016 #ifndef __XEN_PUBLIC_IO_SNDIF_H__ 0017 #define __XEN_PUBLIC_IO_SNDIF_H__ 0018 0019 #include "ring.h" 0020 #include "../grant_table.h" 0021 0022 /* 0023 ****************************************************************************** 0024 * Protocol version 0025 ****************************************************************************** 0026 */ 0027 #define XENSND_PROTOCOL_VERSION 2 0028 0029 /* 0030 ****************************************************************************** 0031 * Feature and Parameter Negotiation 0032 ****************************************************************************** 0033 * 0034 * Front->back notifications: when enqueuing a new request, sending a 0035 * notification can be made conditional on xensnd_req (i.e., the generic 0036 * hold-off mechanism provided by the ring macros). Backends must set 0037 * xensnd_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()). 0038 * 0039 * Back->front notifications: when enqueuing a new response, sending a 0040 * notification can be made conditional on xensnd_resp (i.e., the generic 0041 * hold-off mechanism provided by the ring macros). Frontends must set 0042 * xensnd_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()). 0043 * 0044 * The two halves of a para-virtual sound card driver utilize nodes within 0045 * XenStore to communicate capabilities and to negotiate operating parameters. 0046 * This section enumerates these nodes which reside in the respective front and 0047 * backend portions of XenStore, following the XenBus convention. 0048 * 0049 * All data in XenStore is stored as strings. Nodes specifying numeric 0050 * values are encoded in decimal. Integer value ranges listed below are 0051 * expressed as fixed sized integer types capable of storing the conversion 0052 * of a properly formated node string, without loss of information. 0053 * 0054 ****************************************************************************** 0055 * Example configuration 0056 ****************************************************************************** 0057 * 0058 * Note: depending on the use-case backend can expose more sound cards and 0059 * PCM devices/streams than the underlying HW physically has by employing 0060 * SW mixers, configuring virtual sound streams, channels etc. 0061 * 0062 * This is an example of backend and frontend configuration: 0063 * 0064 *--------------------------------- Backend ----------------------------------- 0065 * 0066 * /local/domain/0/backend/vsnd/1/0/frontend-id = "1" 0067 * /local/domain/0/backend/vsnd/1/0/frontend = "/local/domain/1/device/vsnd/0" 0068 * /local/domain/0/backend/vsnd/1/0/state = "4" 0069 * /local/domain/0/backend/vsnd/1/0/versions = "1,2" 0070 * 0071 *--------------------------------- Frontend ---------------------------------- 0072 * 0073 * /local/domain/1/device/vsnd/0/backend-id = "0" 0074 * /local/domain/1/device/vsnd/0/backend = "/local/domain/0/backend/vsnd/1/0" 0075 * /local/domain/1/device/vsnd/0/state = "4" 0076 * /local/domain/1/device/vsnd/0/version = "1" 0077 * 0078 *----------------------------- Card configuration ---------------------------- 0079 * 0080 * /local/domain/1/device/vsnd/0/short-name = "Card short name" 0081 * /local/domain/1/device/vsnd/0/long-name = "Card long name" 0082 * /local/domain/1/device/vsnd/0/sample-rates = "8000,32000,44100,48000,96000" 0083 * /local/domain/1/device/vsnd/0/sample-formats = "s8,u8,s16_le,s16_be" 0084 * /local/domain/1/device/vsnd/0/buffer-size = "262144" 0085 * 0086 *------------------------------- PCM device 0 -------------------------------- 0087 * 0088 * /local/domain/1/device/vsnd/0/0/name = "General analog" 0089 * /local/domain/1/device/vsnd/0/0/channels-max = "5" 0090 * 0091 *----------------------------- Stream 0, playback ---------------------------- 0092 * 0093 * /local/domain/1/device/vsnd/0/0/0/type = "p" 0094 * /local/domain/1/device/vsnd/0/0/0/sample-formats = "s8,u8" 0095 * /local/domain/1/device/vsnd/0/0/0/unique-id = "0" 0096 * 0097 * /local/domain/1/device/vsnd/0/0/0/ring-ref = "386" 0098 * /local/domain/1/device/vsnd/0/0/0/event-channel = "15" 0099 * /local/domain/1/device/vsnd/0/0/0/evt-ring-ref = "1386" 0100 * /local/domain/1/device/vsnd/0/0/0/evt-event-channel = "215" 0101 * 0102 *------------------------------ Stream 1, capture ---------------------------- 0103 * 0104 * /local/domain/1/device/vsnd/0/0/1/type = "c" 0105 * /local/domain/1/device/vsnd/0/0/1/channels-max = "2" 0106 * /local/domain/1/device/vsnd/0/0/1/unique-id = "1" 0107 * 0108 * /local/domain/1/device/vsnd/0/0/1/ring-ref = "384" 0109 * /local/domain/1/device/vsnd/0/0/1/event-channel = "13" 0110 * /local/domain/1/device/vsnd/0/0/1/evt-ring-ref = "1384" 0111 * /local/domain/1/device/vsnd/0/0/1/evt-event-channel = "213" 0112 * 0113 *------------------------------- PCM device 1 -------------------------------- 0114 * 0115 * /local/domain/1/device/vsnd/0/1/name = "HDMI-0" 0116 * /local/domain/1/device/vsnd/0/1/sample-rates = "8000,32000,44100" 0117 * 0118 *------------------------------ Stream 0, capture ---------------------------- 0119 * 0120 * /local/domain/1/device/vsnd/0/1/0/type = "c" 0121 * /local/domain/1/device/vsnd/0/1/0/unique-id = "2" 0122 * 0123 * /local/domain/1/device/vsnd/0/1/0/ring-ref = "387" 0124 * /local/domain/1/device/vsnd/0/1/0/event-channel = "151" 0125 * /local/domain/1/device/vsnd/0/1/0/evt-ring-ref = "1387" 0126 * /local/domain/1/device/vsnd/0/1/0/evt-event-channel = "351" 0127 * 0128 *------------------------------- PCM device 2 -------------------------------- 0129 * 0130 * /local/domain/1/device/vsnd/0/2/name = "SPDIF" 0131 * 0132 *----------------------------- Stream 0, playback ---------------------------- 0133 * 0134 * /local/domain/1/device/vsnd/0/2/0/type = "p" 0135 * /local/domain/1/device/vsnd/0/2/0/unique-id = "3" 0136 * 0137 * /local/domain/1/device/vsnd/0/2/0/ring-ref = "389" 0138 * /local/domain/1/device/vsnd/0/2/0/event-channel = "152" 0139 * /local/domain/1/device/vsnd/0/2/0/evt-ring-ref = "1389" 0140 * /local/domain/1/device/vsnd/0/2/0/evt-event-channel = "452" 0141 * 0142 ****************************************************************************** 0143 * Backend XenBus Nodes 0144 ****************************************************************************** 0145 * 0146 *----------------------------- Protocol version ------------------------------ 0147 * 0148 * versions 0149 * Values: <string> 0150 * 0151 * List of XENSND_LIST_SEPARATOR separated protocol versions supported 0152 * by the backend. For example "1,2,3". 0153 * 0154 ****************************************************************************** 0155 * Frontend XenBus Nodes 0156 ****************************************************************************** 0157 * 0158 *-------------------------------- Addressing --------------------------------- 0159 * 0160 * dom-id 0161 * Values: <uint16_t> 0162 * 0163 * Domain identifier. 0164 * 0165 * dev-id 0166 * Values: <uint16_t> 0167 * 0168 * Device identifier. 0169 * 0170 * pcm-dev-idx 0171 * Values: <uint8_t> 0172 * 0173 * Zero based contigous index of the PCM device. 0174 * 0175 * stream-idx 0176 * Values: <uint8_t> 0177 * 0178 * Zero based contigous index of the stream of the PCM device. 0179 * 0180 * The following pattern is used for addressing: 0181 * /local/domain/<dom-id>/device/vsnd/<dev-id>/<pcm-dev-idx>/<stream-idx>/... 0182 * 0183 *----------------------------- Protocol version ------------------------------ 0184 * 0185 * version 0186 * Values: <string> 0187 * 0188 * Protocol version, chosen among the ones supported by the backend. 0189 * 0190 *------------------------------- PCM settings -------------------------------- 0191 * 0192 * Every virtualized sound frontend has a set of PCM devices and streams, each 0193 * could be individually configured. Part of the PCM configuration can be 0194 * defined at higher level of the hierarchy and be fully or partially re-used 0195 * by the underlying layers. These configuration values are: 0196 * o number of channels (min/max) 0197 * o supported sample rates 0198 * o supported sample formats. 0199 * E.g. one can define these values for the whole card, device or stream. 0200 * Every underlying layer in turn can re-define some or all of them to better 0201 * fit its needs. For example, card may define number of channels to be 0202 * in [1; 8] range, and some particular stream may be limited to [1; 2] only. 0203 * The rule is that the underlying layer must be a subset of the upper layer 0204 * range. 0205 * 0206 * channels-min 0207 * Values: <uint8_t> 0208 * 0209 * The minimum amount of channels that is supported, [1; channels-max]. 0210 * Optional, if not set or omitted a value of 1 is used. 0211 * 0212 * channels-max 0213 * Values: <uint8_t> 0214 * 0215 * The maximum amount of channels that is supported. 0216 * Must be at least <channels-min>. 0217 * 0218 * sample-rates 0219 * Values: <list of uint32_t> 0220 * 0221 * List of supported sample rates separated by XENSND_LIST_SEPARATOR. 0222 * Sample rates are expressed as a list of decimal values w/o any 0223 * ordering requirement. 0224 * 0225 * sample-formats 0226 * Values: <list of XENSND_PCM_FORMAT_XXX_STR> 0227 * 0228 * List of supported sample formats separated by XENSND_LIST_SEPARATOR. 0229 * Items must not exceed XENSND_SAMPLE_FORMAT_MAX_LEN length. 0230 * 0231 * buffer-size 0232 * Values: <uint32_t> 0233 * 0234 * The maximum size in octets of the buffer to allocate per stream. 0235 * 0236 *----------------------- Virtual sound card settings ------------------------- 0237 * short-name 0238 * Values: <char[32]> 0239 * 0240 * Short name of the virtual sound card. Optional. 0241 * 0242 * long-name 0243 * Values: <char[80]> 0244 * 0245 * Long name of the virtual sound card. Optional. 0246 * 0247 *----------------------------- Device settings ------------------------------- 0248 * name 0249 * Values: <char[80]> 0250 * 0251 * Name of the sound device within the virtual sound card. Optional. 0252 * 0253 *----------------------------- Stream settings ------------------------------- 0254 * 0255 * type 0256 * Values: "p", "c" 0257 * 0258 * Stream type: "p" - playback stream, "c" - capture stream 0259 * 0260 * If both capture and playback are needed then two streams need to be 0261 * defined under the same device. 0262 * 0263 * unique-id 0264 * Values: <string> 0265 * 0266 * After stream initialization it is assigned a unique ID, so every 0267 * stream of the frontend can be identified by the backend by this ID. 0268 * This can be UUID or such. 0269 * 0270 *-------------------- Stream Request Transport Parameters -------------------- 0271 * 0272 * event-channel 0273 * Values: <uint32_t> 0274 * 0275 * The identifier of the Xen event channel used to signal activity 0276 * in the ring buffer. 0277 * 0278 * ring-ref 0279 * Values: <uint32_t> 0280 * 0281 * The Xen grant reference granting permission for the backend to map 0282 * a sole page in a single page sized ring buffer. 0283 * 0284 *--------------------- Stream Event Transport Parameters --------------------- 0285 * 0286 * This communication path is used to deliver asynchronous events from backend 0287 * to frontend, set up per stream. 0288 * 0289 * evt-event-channel 0290 * Values: <uint32_t> 0291 * 0292 * The identifier of the Xen event channel used to signal activity 0293 * in the ring buffer. 0294 * 0295 * evt-ring-ref 0296 * Values: <uint32_t> 0297 * 0298 * The Xen grant reference granting permission for the backend to map 0299 * a sole page in a single page sized ring buffer. 0300 * 0301 ****************************************************************************** 0302 * STATE DIAGRAMS 0303 ****************************************************************************** 0304 * 0305 * Tool stack creates front and back state nodes with initial state 0306 * XenbusStateInitialising. 0307 * Tool stack creates and sets up frontend sound configuration nodes per domain. 0308 * 0309 * Front Back 0310 * ================================= ===================================== 0311 * XenbusStateInitialising XenbusStateInitialising 0312 * o Query backend device identification 0313 * data. 0314 * o Open and validate backend device. 0315 * | 0316 * | 0317 * V 0318 * XenbusStateInitWait 0319 * 0320 * o Query frontend configuration 0321 * o Allocate and initialize 0322 * event channels per configured 0323 * playback/capture stream. 0324 * o Publish transport parameters 0325 * that will be in effect during 0326 * this connection. 0327 * | 0328 * | 0329 * V 0330 * XenbusStateInitialised 0331 * 0332 * o Query frontend transport parameters. 0333 * o Connect to the event channels. 0334 * | 0335 * | 0336 * V 0337 * XenbusStateConnected 0338 * 0339 * o Create and initialize OS 0340 * virtual sound device instances 0341 * as per configuration. 0342 * | 0343 * | 0344 * V 0345 * XenbusStateConnected 0346 * 0347 * XenbusStateUnknown 0348 * XenbusStateClosed 0349 * XenbusStateClosing 0350 * o Remove virtual sound device 0351 * o Remove event channels 0352 * | 0353 * | 0354 * V 0355 * XenbusStateClosed 0356 * 0357 *------------------------------- Recovery flow ------------------------------- 0358 * 0359 * In case of frontend unrecoverable errors backend handles that as 0360 * if frontend goes into the XenbusStateClosed state. 0361 * 0362 * In case of backend unrecoverable errors frontend tries removing 0363 * the virtualized device. If this is possible at the moment of error, 0364 * then frontend goes into the XenbusStateInitialising state and is ready for 0365 * new connection with backend. If the virtualized device is still in use and 0366 * cannot be removed, then frontend goes into the XenbusStateReconfiguring state 0367 * until either the virtualized device removed or backend initiates a new 0368 * connection. On the virtualized device removal frontend goes into the 0369 * XenbusStateInitialising state. 0370 * 0371 * Note on XenbusStateReconfiguring state of the frontend: if backend has 0372 * unrecoverable errors then frontend cannot send requests to the backend 0373 * and thus cannot provide functionality of the virtualized device anymore. 0374 * After backend is back to normal the virtualized device may still hold some 0375 * state: configuration in use, allocated buffers, client application state etc. 0376 * So, in most cases, this will require frontend to implement complex recovery 0377 * reconnect logic. Instead, by going into XenbusStateReconfiguring state, 0378 * frontend will make sure no new clients of the virtualized device are 0379 * accepted, allow existing client(s) to exit gracefully by signaling error 0380 * state etc. 0381 * Once all the clients are gone frontend can reinitialize the virtualized 0382 * device and get into XenbusStateInitialising state again signaling the 0383 * backend that a new connection can be made. 0384 * 0385 * There are multiple conditions possible under which frontend will go from 0386 * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS 0387 * specific. For example: 0388 * 1. The underlying OS framework may provide callbacks to signal that the last 0389 * client of the virtualized device has gone and the device can be removed 0390 * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue) 0391 * to periodically check if this is the right time to re-try removal of 0392 * the virtualized device. 0393 * 3. By any other means. 0394 * 0395 ****************************************************************************** 0396 * PCM FORMATS 0397 ****************************************************************************** 0398 * 0399 * XENSND_PCM_FORMAT_<format>[_<endian>] 0400 * 0401 * format: <S/U/F><bits> or <name> 0402 * S - signed, U - unsigned, F - float 0403 * bits - 8, 16, 24, 32 0404 * name - MU_LAW, GSM, etc. 0405 * 0406 * endian: <LE/BE>, may be absent 0407 * LE - Little endian, BE - Big endian 0408 */ 0409 #define XENSND_PCM_FORMAT_S8 0 0410 #define XENSND_PCM_FORMAT_U8 1 0411 #define XENSND_PCM_FORMAT_S16_LE 2 0412 #define XENSND_PCM_FORMAT_S16_BE 3 0413 #define XENSND_PCM_FORMAT_U16_LE 4 0414 #define XENSND_PCM_FORMAT_U16_BE 5 0415 #define XENSND_PCM_FORMAT_S24_LE 6 0416 #define XENSND_PCM_FORMAT_S24_BE 7 0417 #define XENSND_PCM_FORMAT_U24_LE 8 0418 #define XENSND_PCM_FORMAT_U24_BE 9 0419 #define XENSND_PCM_FORMAT_S32_LE 10 0420 #define XENSND_PCM_FORMAT_S32_BE 11 0421 #define XENSND_PCM_FORMAT_U32_LE 12 0422 #define XENSND_PCM_FORMAT_U32_BE 13 0423 #define XENSND_PCM_FORMAT_F32_LE 14 /* 4-byte float, IEEE-754 32-bit, */ 0424 #define XENSND_PCM_FORMAT_F32_BE 15 /* range -1.0 to 1.0 */ 0425 #define XENSND_PCM_FORMAT_F64_LE 16 /* 8-byte float, IEEE-754 64-bit, */ 0426 #define XENSND_PCM_FORMAT_F64_BE 17 /* range -1.0 to 1.0 */ 0427 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE 18 0428 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE 19 0429 #define XENSND_PCM_FORMAT_MU_LAW 20 0430 #define XENSND_PCM_FORMAT_A_LAW 21 0431 #define XENSND_PCM_FORMAT_IMA_ADPCM 22 0432 #define XENSND_PCM_FORMAT_MPEG 23 0433 #define XENSND_PCM_FORMAT_GSM 24 0434 0435 /* 0436 ****************************************************************************** 0437 * REQUEST CODES 0438 ****************************************************************************** 0439 */ 0440 #define XENSND_OP_OPEN 0 0441 #define XENSND_OP_CLOSE 1 0442 #define XENSND_OP_READ 2 0443 #define XENSND_OP_WRITE 3 0444 #define XENSND_OP_SET_VOLUME 4 0445 #define XENSND_OP_GET_VOLUME 5 0446 #define XENSND_OP_MUTE 6 0447 #define XENSND_OP_UNMUTE 7 0448 #define XENSND_OP_TRIGGER 8 0449 #define XENSND_OP_HW_PARAM_QUERY 9 0450 0451 #define XENSND_OP_TRIGGER_START 0 0452 #define XENSND_OP_TRIGGER_PAUSE 1 0453 #define XENSND_OP_TRIGGER_STOP 2 0454 #define XENSND_OP_TRIGGER_RESUME 3 0455 0456 /* 0457 ****************************************************************************** 0458 * EVENT CODES 0459 ****************************************************************************** 0460 */ 0461 #define XENSND_EVT_CUR_POS 0 0462 0463 /* 0464 ****************************************************************************** 0465 * XENSTORE FIELD AND PATH NAME STRINGS, HELPERS 0466 ****************************************************************************** 0467 */ 0468 #define XENSND_DRIVER_NAME "vsnd" 0469 0470 #define XENSND_LIST_SEPARATOR "," 0471 /* Field names */ 0472 #define XENSND_FIELD_BE_VERSIONS "versions" 0473 #define XENSND_FIELD_FE_VERSION "version" 0474 #define XENSND_FIELD_VCARD_SHORT_NAME "short-name" 0475 #define XENSND_FIELD_VCARD_LONG_NAME "long-name" 0476 #define XENSND_FIELD_RING_REF "ring-ref" 0477 #define XENSND_FIELD_EVT_CHNL "event-channel" 0478 #define XENSND_FIELD_EVT_RING_REF "evt-ring-ref" 0479 #define XENSND_FIELD_EVT_EVT_CHNL "evt-event-channel" 0480 #define XENSND_FIELD_DEVICE_NAME "name" 0481 #define XENSND_FIELD_TYPE "type" 0482 #define XENSND_FIELD_STREAM_UNIQUE_ID "unique-id" 0483 #define XENSND_FIELD_CHANNELS_MIN "channels-min" 0484 #define XENSND_FIELD_CHANNELS_MAX "channels-max" 0485 #define XENSND_FIELD_SAMPLE_RATES "sample-rates" 0486 #define XENSND_FIELD_SAMPLE_FORMATS "sample-formats" 0487 #define XENSND_FIELD_BUFFER_SIZE "buffer-size" 0488 0489 /* Stream type field values. */ 0490 #define XENSND_STREAM_TYPE_PLAYBACK "p" 0491 #define XENSND_STREAM_TYPE_CAPTURE "c" 0492 /* Sample rate max string length */ 0493 #define XENSND_SAMPLE_RATE_MAX_LEN 11 0494 /* Sample format field values */ 0495 #define XENSND_SAMPLE_FORMAT_MAX_LEN 24 0496 0497 #define XENSND_PCM_FORMAT_S8_STR "s8" 0498 #define XENSND_PCM_FORMAT_U8_STR "u8" 0499 #define XENSND_PCM_FORMAT_S16_LE_STR "s16_le" 0500 #define XENSND_PCM_FORMAT_S16_BE_STR "s16_be" 0501 #define XENSND_PCM_FORMAT_U16_LE_STR "u16_le" 0502 #define XENSND_PCM_FORMAT_U16_BE_STR "u16_be" 0503 #define XENSND_PCM_FORMAT_S24_LE_STR "s24_le" 0504 #define XENSND_PCM_FORMAT_S24_BE_STR "s24_be" 0505 #define XENSND_PCM_FORMAT_U24_LE_STR "u24_le" 0506 #define XENSND_PCM_FORMAT_U24_BE_STR "u24_be" 0507 #define XENSND_PCM_FORMAT_S32_LE_STR "s32_le" 0508 #define XENSND_PCM_FORMAT_S32_BE_STR "s32_be" 0509 #define XENSND_PCM_FORMAT_U32_LE_STR "u32_le" 0510 #define XENSND_PCM_FORMAT_U32_BE_STR "u32_be" 0511 #define XENSND_PCM_FORMAT_F32_LE_STR "float_le" 0512 #define XENSND_PCM_FORMAT_F32_BE_STR "float_be" 0513 #define XENSND_PCM_FORMAT_F64_LE_STR "float64_le" 0514 #define XENSND_PCM_FORMAT_F64_BE_STR "float64_be" 0515 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE_STR "iec958_subframe_le" 0516 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE_STR "iec958_subframe_be" 0517 #define XENSND_PCM_FORMAT_MU_LAW_STR "mu_law" 0518 #define XENSND_PCM_FORMAT_A_LAW_STR "a_law" 0519 #define XENSND_PCM_FORMAT_IMA_ADPCM_STR "ima_adpcm" 0520 #define XENSND_PCM_FORMAT_MPEG_STR "mpeg" 0521 #define XENSND_PCM_FORMAT_GSM_STR "gsm" 0522 0523 0524 /* 0525 ****************************************************************************** 0526 * STATUS RETURN CODES 0527 ****************************************************************************** 0528 * 0529 * Status return code is zero on success and -XEN_EXX on failure. 0530 * 0531 ****************************************************************************** 0532 * Assumptions 0533 ****************************************************************************** 0534 * o usage of grant reference 0 as invalid grant reference: 0535 * grant reference 0 is valid, but never exposed to a PV driver, 0536 * because of the fact it is already in use/reserved by the PV console. 0537 * o all references in this document to page sizes must be treated 0538 * as pages of size XEN_PAGE_SIZE unless otherwise noted. 0539 * 0540 ****************************************************************************** 0541 * Description of the protocol between frontend and backend driver 0542 ****************************************************************************** 0543 * 0544 * The two halves of a Para-virtual sound driver communicate with 0545 * each other using shared pages and event channels. 0546 * Shared page contains a ring with request/response packets. 0547 * 0548 * Packets, used for input/output operations, e.g. read/write, set/get volume, 0549 * etc., provide offset/length fields in order to allow asynchronous protocol 0550 * operation with buffer space sharing: part of the buffer allocated at 0551 * XENSND_OP_OPEN can be used for audio samples and part, for example, 0552 * for volume control. 0553 * 0554 * All reserved fields in the structures below must be 0. 0555 * 0556 *---------------------------------- Requests --------------------------------- 0557 * 0558 * All request packets have the same length (64 octets) 0559 * All request packets have common header: 0560 * 0 1 2 3 octet 0561 * +----------------+----------------+----------------+----------------+ 0562 * | id | operation | reserved | 4 0563 * +----------------+----------------+----------------+----------------+ 0564 * | reserved | 8 0565 * +----------------+----------------+----------------+----------------+ 0566 * id - uint16_t, private guest value, echoed in response 0567 * operation - uint8_t, operation code, XENSND_OP_??? 0568 * 0569 * For all packets which use offset and length: 0570 * offset - uint32_t, read or write data offset within the shared buffer, 0571 * passed with XENSND_OP_OPEN request, octets, 0572 * [0; XENSND_OP_OPEN.buffer_sz - 1]. 0573 * length - uint32_t, read or write data length, octets 0574 * 0575 * Request open - open a PCM stream for playback or capture: 0576 * 0577 * 0 1 2 3 octet 0578 * +----------------+----------------+----------------+----------------+ 0579 * | id | XENSND_OP_OPEN | reserved | 4 0580 * +----------------+----------------+----------------+----------------+ 0581 * | reserved | 8 0582 * +----------------+----------------+----------------+----------------+ 0583 * | pcm_rate | 12 0584 * +----------------+----------------+----------------+----------------+ 0585 * | pcm_format | pcm_channels | reserved | 16 0586 * +----------------+----------------+----------------+----------------+ 0587 * | buffer_sz | 20 0588 * +----------------+----------------+----------------+----------------+ 0589 * | gref_directory | 24 0590 * +----------------+----------------+----------------+----------------+ 0591 * | period_sz | 28 0592 * +----------------+----------------+----------------+----------------+ 0593 * | reserved | 32 0594 * +----------------+----------------+----------------+----------------+ 0595 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0596 * +----------------+----------------+----------------+----------------+ 0597 * | reserved | 64 0598 * +----------------+----------------+----------------+----------------+ 0599 * 0600 * pcm_rate - uint32_t, stream data rate, Hz 0601 * pcm_format - uint8_t, XENSND_PCM_FORMAT_XXX value 0602 * pcm_channels - uint8_t, number of channels of this stream, 0603 * [channels-min; channels-max] 0604 * buffer_sz - uint32_t, buffer size to be allocated, octets 0605 * period_sz - uint32_t, event period size, octets 0606 * This is the requested value of the period at which frontend would 0607 * like to receive XENSND_EVT_CUR_POS notifications from the backend when 0608 * stream position advances during playback/capture. 0609 * It shows how many octets are expected to be played/captured before 0610 * sending such an event. 0611 * If set to 0 no XENSND_EVT_CUR_POS events are sent by the backend. 0612 * 0613 * gref_directory - grant_ref_t, a reference to the first shared page 0614 * describing shared buffer references. At least one page exists. If shared 0615 * buffer size (buffer_sz) exceeds what can be addressed by this single page, 0616 * then reference to the next page must be supplied (see gref_dir_next_page 0617 * below) 0618 */ 0619 0620 struct xensnd_open_req { 0621 uint32_t pcm_rate; 0622 uint8_t pcm_format; 0623 uint8_t pcm_channels; 0624 uint16_t reserved; 0625 uint32_t buffer_sz; 0626 grant_ref_t gref_directory; 0627 uint32_t period_sz; 0628 }; 0629 0630 /* 0631 * Shared page for XENSND_OP_OPEN buffer descriptor (gref_directory in the 0632 * request) employs a list of pages, describing all pages of the shared data 0633 * buffer: 0634 * 0 1 2 3 octet 0635 * +----------------+----------------+----------------+----------------+ 0636 * | gref_dir_next_page | 4 0637 * +----------------+----------------+----------------+----------------+ 0638 * | gref[0] | 8 0639 * +----------------+----------------+----------------+----------------+ 0640 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0641 * +----------------+----------------+----------------+----------------+ 0642 * | gref[i] | i*4+8 0643 * +----------------+----------------+----------------+----------------+ 0644 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0645 * +----------------+----------------+----------------+----------------+ 0646 * | gref[N - 1] | N*4+8 0647 * +----------------+----------------+----------------+----------------+ 0648 * 0649 * gref_dir_next_page - grant_ref_t, reference to the next page describing 0650 * page directory. Must be 0 if there are no more pages in the list. 0651 * gref[i] - grant_ref_t, reference to a shared page of the buffer 0652 * allocated at XENSND_OP_OPEN 0653 * 0654 * Number of grant_ref_t entries in the whole page directory is not 0655 * passed, but instead can be calculated as: 0656 * num_grefs_total = (XENSND_OP_OPEN.buffer_sz + XEN_PAGE_SIZE - 1) / 0657 * XEN_PAGE_SIZE 0658 */ 0659 0660 struct xensnd_page_directory { 0661 grant_ref_t gref_dir_next_page; 0662 grant_ref_t gref[1]; /* Variable length */ 0663 }; 0664 0665 /* 0666 * Request close - close an opened pcm stream: 0667 * 0 1 2 3 octet 0668 * +----------------+----------------+----------------+----------------+ 0669 * | id | XENSND_OP_CLOSE| reserved | 4 0670 * +----------------+----------------+----------------+----------------+ 0671 * | reserved | 8 0672 * +----------------+----------------+----------------+----------------+ 0673 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0674 * +----------------+----------------+----------------+----------------+ 0675 * | reserved | 64 0676 * +----------------+----------------+----------------+----------------+ 0677 * 0678 * Request read/write - used for read (for capture) or write (for playback): 0679 * 0 1 2 3 octet 0680 * +----------------+----------------+----------------+----------------+ 0681 * | id | operation | reserved | 4 0682 * +----------------+----------------+----------------+----------------+ 0683 * | reserved | 8 0684 * +----------------+----------------+----------------+----------------+ 0685 * | offset | 12 0686 * +----------------+----------------+----------------+----------------+ 0687 * | length | 16 0688 * +----------------+----------------+----------------+----------------+ 0689 * | reserved | 20 0690 * +----------------+----------------+----------------+----------------+ 0691 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0692 * +----------------+----------------+----------------+----------------+ 0693 * | reserved | 64 0694 * +----------------+----------------+----------------+----------------+ 0695 * 0696 * operation - XENSND_OP_READ for read or XENSND_OP_WRITE for write 0697 */ 0698 0699 struct xensnd_rw_req { 0700 uint32_t offset; 0701 uint32_t length; 0702 }; 0703 0704 /* 0705 * Request set/get volume - set/get channels' volume of the stream given: 0706 * 0 1 2 3 octet 0707 * +----------------+----------------+----------------+----------------+ 0708 * | id | operation | reserved | 4 0709 * +----------------+----------------+----------------+----------------+ 0710 * | reserved | 8 0711 * +----------------+----------------+----------------+----------------+ 0712 * | offset | 12 0713 * +----------------+----------------+----------------+----------------+ 0714 * | length | 16 0715 * +----------------+----------------+----------------+----------------+ 0716 * | reserved | 20 0717 * +----------------+----------------+----------------+----------------+ 0718 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0719 * +----------------+----------------+----------------+----------------+ 0720 * | reserved | 64 0721 * +----------------+----------------+----------------+----------------+ 0722 * 0723 * operation - XENSND_OP_SET_VOLUME for volume set 0724 * or XENSND_OP_GET_VOLUME for volume get 0725 * Buffer passed with XENSND_OP_OPEN is used to exchange volume 0726 * values: 0727 * 0728 * 0 1 2 3 octet 0729 * +----------------+----------------+----------------+----------------+ 0730 * | channel[0] | 4 0731 * +----------------+----------------+----------------+----------------+ 0732 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0733 * +----------------+----------------+----------------+----------------+ 0734 * | channel[i] | i*4 0735 * +----------------+----------------+----------------+----------------+ 0736 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0737 * +----------------+----------------+----------------+----------------+ 0738 * | channel[N - 1] | (N-1)*4 0739 * +----------------+----------------+----------------+----------------+ 0740 * 0741 * N = XENSND_OP_OPEN.pcm_channels 0742 * i - uint8_t, index of a channel 0743 * channel[i] - sint32_t, volume of i-th channel 0744 * Volume is expressed as a signed value in steps of 0.001 dB, 0745 * while 0 being 0 dB. 0746 * 0747 * Request mute/unmute - mute/unmute stream: 0748 * 0 1 2 3 octet 0749 * +----------------+----------------+----------------+----------------+ 0750 * | id | operation | reserved | 4 0751 * +----------------+----------------+----------------+----------------+ 0752 * | reserved | 8 0753 * +----------------+----------------+----------------+----------------+ 0754 * | offset | 12 0755 * +----------------+----------------+----------------+----------------+ 0756 * | length | 16 0757 * +----------------+----------------+----------------+----------------+ 0758 * | reserved | 20 0759 * +----------------+----------------+----------------+----------------+ 0760 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0761 * +----------------+----------------+----------------+----------------+ 0762 * | reserved | 64 0763 * +----------------+----------------+----------------+----------------+ 0764 * 0765 * operation - XENSND_OP_MUTE for mute or XENSND_OP_UNMUTE for unmute 0766 * Buffer passed with XENSND_OP_OPEN is used to exchange mute/unmute 0767 * values: 0768 * 0769 * 0 octet 0770 * +----------------+----------------+----------------+----------------+ 0771 * | channel[0] | 4 0772 * +----------------+----------------+----------------+----------------+ 0773 * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0774 * +----------------+----------------+----------------+----------------+ 0775 * | channel[i] | i*4 0776 * +----------------+----------------+----------------+----------------+ 0777 * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0778 * +----------------+----------------+----------------+----------------+ 0779 * | channel[N - 1] | (N-1)*4 0780 * +----------------+----------------+----------------+----------------+ 0781 * 0782 * N = XENSND_OP_OPEN.pcm_channels 0783 * i - uint8_t, index of a channel 0784 * channel[i] - uint8_t, non-zero if i-th channel needs to be muted/unmuted 0785 * 0786 *------------------------------------ N.B. ----------------------------------- 0787 * 0788 * The 'struct xensnd_rw_req' is also used for XENSND_OP_SET_VOLUME, 0789 * XENSND_OP_GET_VOLUME, XENSND_OP_MUTE, XENSND_OP_UNMUTE. 0790 * 0791 * Request stream running state change - trigger PCM stream running state 0792 * to start, stop, pause or resume: 0793 * 0794 * 0 1 2 3 octet 0795 * +----------------+----------------+----------------+----------------+ 0796 * | id | _OP_TRIGGER | reserved | 4 0797 * +----------------+----------------+----------------+----------------+ 0798 * | reserved | 8 0799 * +----------------+----------------+----------------+----------------+ 0800 * | type | reserved | 12 0801 * +----------------+----------------+----------------+----------------+ 0802 * | reserved | 16 0803 * +----------------+----------------+----------------+----------------+ 0804 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0805 * +----------------+----------------+----------------+----------------+ 0806 * | reserved | 64 0807 * +----------------+----------------+----------------+----------------+ 0808 * 0809 * type - uint8_t, XENSND_OP_TRIGGER_XXX value 0810 */ 0811 0812 struct xensnd_trigger_req { 0813 uint8_t type; 0814 }; 0815 0816 /* 0817 * Request stream parameter ranges: request intervals and 0818 * masks of supported ranges for stream configuration values. 0819 * 0820 * Sound device configuration for a particular stream is a limited subset 0821 * of the multidimensional configuration available on XenStore, e.g. 0822 * once the frame rate has been selected there is a limited supported range 0823 * for sample rates becomes available (which might be the same set configured 0824 * on XenStore or less). For example, selecting 96kHz sample rate may limit 0825 * number of channels available for such configuration from 4 to 2, etc. 0826 * Thus, each call to XENSND_OP_HW_PARAM_QUERY may reduce configuration 0827 * space making it possible to iteratively get the final stream configuration, 0828 * used in XENSND_OP_OPEN request. 0829 * 0830 * See response format for this request. 0831 * 0832 * 0 1 2 3 octet 0833 * +----------------+----------------+----------------+----------------+ 0834 * | id | _HW_PARAM_QUERY| reserved | 4 0835 * +----------------+----------------+----------------+----------------+ 0836 * | reserved | 8 0837 * +----------------+----------------+----------------+----------------+ 0838 * | formats mask low 32-bit | 12 0839 * +----------------+----------------+----------------+----------------+ 0840 * | formats mask high 32-bit | 16 0841 * +----------------+----------------+----------------+----------------+ 0842 * | min rate | 20 0843 * +----------------+----------------+----------------+----------------+ 0844 * | max rate | 24 0845 * +----------------+----------------+----------------+----------------+ 0846 * | min channels | 28 0847 * +----------------+----------------+----------------+----------------+ 0848 * | max channels | 32 0849 * +----------------+----------------+----------------+----------------+ 0850 * | min buffer frames | 36 0851 * +----------------+----------------+----------------+----------------+ 0852 * | max buffer frames | 40 0853 * +----------------+----------------+----------------+----------------+ 0854 * | min period frames | 44 0855 * +----------------+----------------+----------------+----------------+ 0856 * | max period frames | 48 0857 * +----------------+----------------+----------------+----------------+ 0858 * | reserved | 52 0859 * +----------------+----------------+----------------+----------------+ 0860 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0861 * +----------------+----------------+----------------+----------------+ 0862 * | reserved | 64 0863 * +----------------+----------------+----------------+----------------+ 0864 * 0865 * formats - uint64_t, bit mask representing values of the parameter 0866 * made as bitwise OR of (1 << XENSND_PCM_FORMAT_XXX) values 0867 * 0868 * For interval parameters: 0869 * min - uint32_t, minimum value of the parameter 0870 * max - uint32_t, maximum value of the parameter 0871 * 0872 * Frame is defined as a product of the number of channels by the 0873 * number of octets per one sample. 0874 */ 0875 0876 struct xensnd_query_hw_param { 0877 uint64_t formats; 0878 struct { 0879 uint32_t min; 0880 uint32_t max; 0881 } rates; 0882 struct { 0883 uint32_t min; 0884 uint32_t max; 0885 } channels; 0886 struct { 0887 uint32_t min; 0888 uint32_t max; 0889 } buffer; 0890 struct { 0891 uint32_t min; 0892 uint32_t max; 0893 } period; 0894 }; 0895 0896 /* 0897 *---------------------------------- Responses -------------------------------- 0898 * 0899 * All response packets have the same length (64 octets) 0900 * 0901 * All response packets have common header: 0902 * 0 1 2 3 octet 0903 * +----------------+----------------+----------------+----------------+ 0904 * | id | operation | reserved | 4 0905 * +----------------+----------------+----------------+----------------+ 0906 * | status | 8 0907 * +----------------+----------------+----------------+----------------+ 0908 * 0909 * id - uint16_t, copied from the request 0910 * operation - uint8_t, XENSND_OP_* - copied from request 0911 * status - int32_t, response status, zero on success and -XEN_EXX on failure 0912 * 0913 * 0914 * HW parameter query response - response for XENSND_OP_HW_PARAM_QUERY: 0915 * 0 1 2 3 octet 0916 * +----------------+----------------+----------------+----------------+ 0917 * | id | operation | reserved | 4 0918 * +----------------+----------------+----------------+----------------+ 0919 * | status | 8 0920 * +----------------+----------------+----------------+----------------+ 0921 * | formats mask low 32-bit | 12 0922 * +----------------+----------------+----------------+----------------+ 0923 * | formats mask high 32-bit | 16 0924 * +----------------+----------------+----------------+----------------+ 0925 * | min rate | 20 0926 * +----------------+----------------+----------------+----------------+ 0927 * | max rate | 24 0928 * +----------------+----------------+----------------+----------------+ 0929 * | min channels | 28 0930 * +----------------+----------------+----------------+----------------+ 0931 * | max channels | 32 0932 * +----------------+----------------+----------------+----------------+ 0933 * | min buffer frames | 36 0934 * +----------------+----------------+----------------+----------------+ 0935 * | max buffer frames | 40 0936 * +----------------+----------------+----------------+----------------+ 0937 * | min period frames | 44 0938 * +----------------+----------------+----------------+----------------+ 0939 * | max period frames | 48 0940 * +----------------+----------------+----------------+----------------+ 0941 * | reserved | 52 0942 * +----------------+----------------+----------------+----------------+ 0943 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0944 * +----------------+----------------+----------------+----------------+ 0945 * | reserved | 64 0946 * +----------------+----------------+----------------+----------------+ 0947 * 0948 * Meaning of the values in this response is the same as for 0949 * XENSND_OP_HW_PARAM_QUERY request. 0950 */ 0951 0952 /* 0953 *----------------------------------- Events ---------------------------------- 0954 * 0955 * Events are sent via shared page allocated by the front and propagated by 0956 * evt-event-channel/evt-ring-ref XenStore entries 0957 * All event packets have the same length (64 octets) 0958 * All event packets have common header: 0959 * 0 1 2 3 octet 0960 * +----------------+----------------+----------------+----------------+ 0961 * | id | type | reserved | 4 0962 * +----------------+----------------+----------------+----------------+ 0963 * | reserved | 8 0964 * +----------------+----------------+----------------+----------------+ 0965 * 0966 * id - uint16_t, event id, may be used by front 0967 * type - uint8_t, type of the event 0968 * 0969 * 0970 * Current stream position - event from back to front when stream's 0971 * playback/capture position has advanced: 0972 * 0 1 2 3 octet 0973 * +----------------+----------------+----------------+----------------+ 0974 * | id | _EVT_CUR_POS | reserved | 4 0975 * +----------------+----------------+----------------+----------------+ 0976 * | reserved | 8 0977 * +----------------+----------------+----------------+----------------+ 0978 * | position low 32-bit | 12 0979 * +----------------+----------------+----------------+----------------+ 0980 * | position high 32-bit | 16 0981 * +----------------+----------------+----------------+----------------+ 0982 * | reserved | 20 0983 * +----------------+----------------+----------------+----------------+ 0984 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 0985 * +----------------+----------------+----------------+----------------+ 0986 * | reserved | 64 0987 * +----------------+----------------+----------------+----------------+ 0988 * 0989 * position - current value of stream's playback/capture position, octets 0990 * 0991 */ 0992 0993 struct xensnd_cur_pos_evt { 0994 uint64_t position; 0995 }; 0996 0997 struct xensnd_req { 0998 uint16_t id; 0999 uint8_t operation; 1000 uint8_t reserved[5]; 1001 union { 1002 struct xensnd_open_req open; 1003 struct xensnd_rw_req rw; 1004 struct xensnd_trigger_req trigger; 1005 struct xensnd_query_hw_param hw_param; 1006 uint8_t reserved[56]; 1007 } op; 1008 }; 1009 1010 struct xensnd_resp { 1011 uint16_t id; 1012 uint8_t operation; 1013 uint8_t reserved; 1014 int32_t status; 1015 union { 1016 struct xensnd_query_hw_param hw_param; 1017 uint8_t reserved1[56]; 1018 } resp; 1019 }; 1020 1021 struct xensnd_evt { 1022 uint16_t id; 1023 uint8_t type; 1024 uint8_t reserved[5]; 1025 union { 1026 struct xensnd_cur_pos_evt cur_pos; 1027 uint8_t reserved[56]; 1028 } op; 1029 }; 1030 1031 DEFINE_RING_TYPES(xen_sndif, struct xensnd_req, struct xensnd_resp); 1032 1033 /* 1034 ****************************************************************************** 1035 * Back to front events delivery 1036 ****************************************************************************** 1037 * In order to deliver asynchronous events from back to front a shared page is 1038 * allocated by front and its granted reference propagated to back via 1039 * XenStore entries (evt-ring-ref/evt-event-channel). 1040 * This page has a common header used by both front and back to synchronize 1041 * access and control event's ring buffer, while back being a producer of the 1042 * events and front being a consumer. The rest of the page after the header 1043 * is used for event packets. 1044 * 1045 * Upon reception of an event(s) front may confirm its reception 1046 * for either each event, group of events or none. 1047 */ 1048 1049 struct xensnd_event_page { 1050 uint32_t in_cons; 1051 uint32_t in_prod; 1052 uint8_t reserved[56]; 1053 }; 1054 1055 #define XENSND_EVENT_PAGE_SIZE XEN_PAGE_SIZE 1056 #define XENSND_IN_RING_OFFS (sizeof(struct xensnd_event_page)) 1057 #define XENSND_IN_RING_SIZE (XENSND_EVENT_PAGE_SIZE - XENSND_IN_RING_OFFS) 1058 #define XENSND_IN_RING_LEN (XENSND_IN_RING_SIZE / sizeof(struct xensnd_evt)) 1059 #define XENSND_IN_RING(page) \ 1060 ((struct xensnd_evt *)((char *)(page) + XENSND_IN_RING_OFFS)) 1061 #define XENSND_IN_RING_REF(page, idx) \ 1062 (XENSND_IN_RING((page))[(idx) % XENSND_IN_RING_LEN]) 1063 1064 #endif /* __XEN_PUBLIC_IO_SNDIF_H__ */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |