1 /****************************************************************************** 2 * sndif.h 3 * 4 * Unified sound-device I/O interface for Xen guest OSes. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 * Copyright (C) 2013-2015 GlobalLogic Inc. 25 * Copyright (C) 2016-2017 EPAM Systems Inc. 26 * 27 * Authors: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 28 * Oleksandr Grytsov <oleksandr_grytsov@epam.com> 29 * Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com> 30 * Iurii Konovalenko <iurii.konovalenko@globallogic.com> 31 */ 32 33 #ifndef __XEN_PUBLIC_IO_SNDIF_H__ 34 #define __XEN_PUBLIC_IO_SNDIF_H__ 35 36 #include "ring.h" 37 #include "../grant_table.h" 38 39 /* 40 ****************************************************************************** 41 * Protocol version 42 ****************************************************************************** 43 */ 44 #define XENSND_PROTOCOL_VERSION 2 45 46 /* 47 ****************************************************************************** 48 * Feature and Parameter Negotiation 49 ****************************************************************************** 50 * 51 * Front->back notifications: when enqueuing a new request, sending a 52 * notification can be made conditional on xensnd_req (i.e., the generic 53 * hold-off mechanism provided by the ring macros). Backends must set 54 * xensnd_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()). 55 * 56 * Back->front notifications: when enqueuing a new response, sending a 57 * notification can be made conditional on xensnd_resp (i.e., the generic 58 * hold-off mechanism provided by the ring macros). Frontends must set 59 * xensnd_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()). 60 * 61 * The two halves of a para-virtual sound card driver utilize nodes within 62 * XenStore to communicate capabilities and to negotiate operating parameters. 63 * This section enumerates these nodes which reside in the respective front and 64 * backend portions of XenStore, following the XenBus convention. 65 * 66 * All data in XenStore is stored as strings. Nodes specifying numeric 67 * values are encoded in decimal. Integer value ranges listed below are 68 * expressed as fixed sized integer types capable of storing the conversion 69 * of a properly formated node string, without loss of information. 70 * 71 ****************************************************************************** 72 * Example configuration 73 ****************************************************************************** 74 * 75 * Note: depending on the use-case backend can expose more sound cards and 76 * PCM devices/streams than the underlying HW physically has by employing 77 * SW mixers, configuring virtual sound streams, channels etc. 78 * 79 * This is an example of backend and frontend configuration: 80 * 81 *--------------------------------- Backend ----------------------------------- 82 * 83 * /local/domain/0/backend/vsnd/1/0/frontend-id = "1" 84 * /local/domain/0/backend/vsnd/1/0/frontend = "/local/domain/1/device/vsnd/0" 85 * /local/domain/0/backend/vsnd/1/0/state = "4" 86 * /local/domain/0/backend/vsnd/1/0/versions = "1,2" 87 * 88 *--------------------------------- Frontend ---------------------------------- 89 * 90 * /local/domain/1/device/vsnd/0/backend-id = "0" 91 * /local/domain/1/device/vsnd/0/backend = "/local/domain/0/backend/vsnd/1/0" 92 * /local/domain/1/device/vsnd/0/state = "4" 93 * /local/domain/1/device/vsnd/0/version = "1" 94 * 95 *----------------------------- Card configuration ---------------------------- 96 * 97 * /local/domain/1/device/vsnd/0/short-name = "Card short name" 98 * /local/domain/1/device/vsnd/0/long-name = "Card long name" 99 * /local/domain/1/device/vsnd/0/sample-rates = "8000,32000,44100,48000,96000" 100 * /local/domain/1/device/vsnd/0/sample-formats = "s8,u8,s16_le,s16_be" 101 * /local/domain/1/device/vsnd/0/buffer-size = "262144" 102 * 103 *------------------------------- PCM device 0 -------------------------------- 104 * 105 * /local/domain/1/device/vsnd/0/0/name = "General analog" 106 * /local/domain/1/device/vsnd/0/0/channels-max = "5" 107 * 108 *----------------------------- Stream 0, playback ---------------------------- 109 * 110 * /local/domain/1/device/vsnd/0/0/0/type = "p" 111 * /local/domain/1/device/vsnd/0/0/0/sample-formats = "s8,u8" 112 * /local/domain/1/device/vsnd/0/0/0/unique-id = "0" 113 * 114 * /local/domain/1/device/vsnd/0/0/0/ring-ref = "386" 115 * /local/domain/1/device/vsnd/0/0/0/event-channel = "15" 116 * /local/domain/1/device/vsnd/0/0/0/evt-ring-ref = "1386" 117 * /local/domain/1/device/vsnd/0/0/0/evt-event-channel = "215" 118 * 119 *------------------------------ Stream 1, capture ---------------------------- 120 * 121 * /local/domain/1/device/vsnd/0/0/1/type = "c" 122 * /local/domain/1/device/vsnd/0/0/1/channels-max = "2" 123 * /local/domain/1/device/vsnd/0/0/1/unique-id = "1" 124 * 125 * /local/domain/1/device/vsnd/0/0/1/ring-ref = "384" 126 * /local/domain/1/device/vsnd/0/0/1/event-channel = "13" 127 * /local/domain/1/device/vsnd/0/0/1/evt-ring-ref = "1384" 128 * /local/domain/1/device/vsnd/0/0/1/evt-event-channel = "213" 129 * 130 *------------------------------- PCM device 1 -------------------------------- 131 * 132 * /local/domain/1/device/vsnd/0/1/name = "HDMI-0" 133 * /local/domain/1/device/vsnd/0/1/sample-rates = "8000,32000,44100" 134 * 135 *------------------------------ Stream 0, capture ---------------------------- 136 * 137 * /local/domain/1/device/vsnd/0/1/0/type = "c" 138 * /local/domain/1/device/vsnd/0/1/0/unique-id = "2" 139 * 140 * /local/domain/1/device/vsnd/0/1/0/ring-ref = "387" 141 * /local/domain/1/device/vsnd/0/1/0/event-channel = "151" 142 * /local/domain/1/device/vsnd/0/1/0/evt-ring-ref = "1387" 143 * /local/domain/1/device/vsnd/0/1/0/evt-event-channel = "351" 144 * 145 *------------------------------- PCM device 2 -------------------------------- 146 * 147 * /local/domain/1/device/vsnd/0/2/name = "SPDIF" 148 * 149 *----------------------------- Stream 0, playback ---------------------------- 150 * 151 * /local/domain/1/device/vsnd/0/2/0/type = "p" 152 * /local/domain/1/device/vsnd/0/2/0/unique-id = "3" 153 * 154 * /local/domain/1/device/vsnd/0/2/0/ring-ref = "389" 155 * /local/domain/1/device/vsnd/0/2/0/event-channel = "152" 156 * /local/domain/1/device/vsnd/0/2/0/evt-ring-ref = "1389" 157 * /local/domain/1/device/vsnd/0/2/0/evt-event-channel = "452" 158 * 159 ****************************************************************************** 160 * Backend XenBus Nodes 161 ****************************************************************************** 162 * 163 *----------------------------- Protocol version ------------------------------ 164 * 165 * versions 166 * Values: <string> 167 * 168 * List of XENSND_LIST_SEPARATOR separated protocol versions supported 169 * by the backend. For example "1,2,3". 170 * 171 ****************************************************************************** 172 * Frontend XenBus Nodes 173 ****************************************************************************** 174 * 175 *-------------------------------- Addressing --------------------------------- 176 * 177 * dom-id 178 * Values: <uint16_t> 179 * 180 * Domain identifier. 181 * 182 * dev-id 183 * Values: <uint16_t> 184 * 185 * Device identifier. 186 * 187 * pcm-dev-idx 188 * Values: <uint8_t> 189 * 190 * Zero based contigous index of the PCM device. 191 * 192 * stream-idx 193 * Values: <uint8_t> 194 * 195 * Zero based contigous index of the stream of the PCM device. 196 * 197 * The following pattern is used for addressing: 198 * /local/domain/<dom-id>/device/vsnd/<dev-id>/<pcm-dev-idx>/<stream-idx>/... 199 * 200 *----------------------------- Protocol version ------------------------------ 201 * 202 * version 203 * Values: <string> 204 * 205 * Protocol version, chosen among the ones supported by the backend. 206 * 207 *------------------------------- PCM settings -------------------------------- 208 * 209 * Every virtualized sound frontend has a set of PCM devices and streams, each 210 * could be individually configured. Part of the PCM configuration can be 211 * defined at higher level of the hierarchy and be fully or partially re-used 212 * by the underlying layers. These configuration values are: 213 * o number of channels (min/max) 214 * o supported sample rates 215 * o supported sample formats. 216 * E.g. one can define these values for the whole card, device or stream. 217 * Every underlying layer in turn can re-define some or all of them to better 218 * fit its needs. For example, card may define number of channels to be 219 * in [1; 8] range, and some particular stream may be limited to [1; 2] only. 220 * The rule is that the underlying layer must be a subset of the upper layer 221 * range. 222 * 223 * channels-min 224 * Values: <uint8_t> 225 * 226 * The minimum amount of channels that is supported, [1; channels-max]. 227 * Optional, if not set or omitted a value of 1 is used. 228 * 229 * channels-max 230 * Values: <uint8_t> 231 * 232 * The maximum amount of channels that is supported. 233 * Must be at least <channels-min>. 234 * 235 * sample-rates 236 * Values: <list of uint32_t> 237 * 238 * List of supported sample rates separated by XENSND_LIST_SEPARATOR. 239 * Sample rates are expressed as a list of decimal values w/o any 240 * ordering requirement. 241 * 242 * sample-formats 243 * Values: <list of XENSND_PCM_FORMAT_XXX_STR> 244 * 245 * List of supported sample formats separated by XENSND_LIST_SEPARATOR. 246 * Items must not exceed XENSND_SAMPLE_FORMAT_MAX_LEN length. 247 * 248 * buffer-size 249 * Values: <uint32_t> 250 * 251 * The maximum size in octets of the buffer to allocate per stream. 252 * 253 *----------------------- Virtual sound card settings ------------------------- 254 * short-name 255 * Values: <char[32]> 256 * 257 * Short name of the virtual sound card. Optional. 258 * 259 * long-name 260 * Values: <char[80]> 261 * 262 * Long name of the virtual sound card. Optional. 263 * 264 *----------------------------- Device settings ------------------------------- 265 * name 266 * Values: <char[80]> 267 * 268 * Name of the sound device within the virtual sound card. Optional. 269 * 270 *----------------------------- Stream settings ------------------------------- 271 * 272 * type 273 * Values: "p", "c" 274 * 275 * Stream type: "p" - playback stream, "c" - capture stream 276 * 277 * If both capture and playback are needed then two streams need to be 278 * defined under the same device. 279 * 280 * unique-id 281 * Values: <string> 282 * 283 * After stream initialization it is assigned a unique ID, so every 284 * stream of the frontend can be identified by the backend by this ID. 285 * This can be UUID or such. 286 * 287 *-------------------- Stream Request Transport Parameters -------------------- 288 * 289 * event-channel 290 * Values: <uint32_t> 291 * 292 * The identifier of the Xen event channel used to signal activity 293 * in the ring buffer. 294 * 295 * ring-ref 296 * Values: <uint32_t> 297 * 298 * The Xen grant reference granting permission for the backend to map 299 * a sole page in a single page sized ring buffer. 300 * 301 *--------------------- Stream Event Transport Parameters --------------------- 302 * 303 * This communication path is used to deliver asynchronous events from backend 304 * to frontend, set up per stream. 305 * 306 * evt-event-channel 307 * Values: <uint32_t> 308 * 309 * The identifier of the Xen event channel used to signal activity 310 * in the ring buffer. 311 * 312 * evt-ring-ref 313 * Values: <uint32_t> 314 * 315 * The Xen grant reference granting permission for the backend to map 316 * a sole page in a single page sized ring buffer. 317 * 318 ****************************************************************************** 319 * STATE DIAGRAMS 320 ****************************************************************************** 321 * 322 * Tool stack creates front and back state nodes with initial state 323 * XenbusStateInitialising. 324 * Tool stack creates and sets up frontend sound configuration nodes per domain. 325 * 326 * Front Back 327 * ================================= ===================================== 328 * XenbusStateInitialising XenbusStateInitialising 329 * o Query backend device identification 330 * data. 331 * o Open and validate backend device. 332 * | 333 * | 334 * V 335 * XenbusStateInitWait 336 * 337 * o Query frontend configuration 338 * o Allocate and initialize 339 * event channels per configured 340 * playback/capture stream. 341 * o Publish transport parameters 342 * that will be in effect during 343 * this connection. 344 * | 345 * | 346 * V 347 * XenbusStateInitialised 348 * 349 * o Query frontend transport parameters. 350 * o Connect to the event channels. 351 * | 352 * | 353 * V 354 * XenbusStateConnected 355 * 356 * o Create and initialize OS 357 * virtual sound device instances 358 * as per configuration. 359 * | 360 * | 361 * V 362 * XenbusStateConnected 363 * 364 * XenbusStateUnknown 365 * XenbusStateClosed 366 * XenbusStateClosing 367 * o Remove virtual sound device 368 * o Remove event channels 369 * | 370 * | 371 * V 372 * XenbusStateClosed 373 * 374 *------------------------------- Recovery flow ------------------------------- 375 * 376 * In case of frontend unrecoverable errors backend handles that as 377 * if frontend goes into the XenbusStateClosed state. 378 * 379 * In case of backend unrecoverable errors frontend tries removing 380 * the virtualized device. If this is possible at the moment of error, 381 * then frontend goes into the XenbusStateInitialising state and is ready for 382 * new connection with backend. If the virtualized device is still in use and 383 * cannot be removed, then frontend goes into the XenbusStateReconfiguring state 384 * until either the virtualized device removed or backend initiates a new 385 * connection. On the virtualized device removal frontend goes into the 386 * XenbusStateInitialising state. 387 * 388 * Note on XenbusStateReconfiguring state of the frontend: if backend has 389 * unrecoverable errors then frontend cannot send requests to the backend 390 * and thus cannot provide functionality of the virtualized device anymore. 391 * After backend is back to normal the virtualized device may still hold some 392 * state: configuration in use, allocated buffers, client application state etc. 393 * So, in most cases, this will require frontend to implement complex recovery 394 * reconnect logic. Instead, by going into XenbusStateReconfiguring state, 395 * frontend will make sure no new clients of the virtualized device are 396 * accepted, allow existing client(s) to exit gracefully by signaling error 397 * state etc. 398 * Once all the clients are gone frontend can reinitialize the virtualized 399 * device and get into XenbusStateInitialising state again signaling the 400 * backend that a new connection can be made. 401 * 402 * There are multiple conditions possible under which frontend will go from 403 * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS 404 * specific. For example: 405 * 1. The underlying OS framework may provide callbacks to signal that the last 406 * client of the virtualized device has gone and the device can be removed 407 * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue) 408 * to periodically check if this is the right time to re-try removal of 409 * the virtualized device. 410 * 3. By any other means. 411 * 412 ****************************************************************************** 413 * PCM FORMATS 414 ****************************************************************************** 415 * 416 * XENSND_PCM_FORMAT_<format>[_<endian>] 417 * 418 * format: <S/U/F><bits> or <name> 419 * S - signed, U - unsigned, F - float 420 * bits - 8, 16, 24, 32 421 * name - MU_LAW, GSM, etc. 422 * 423 * endian: <LE/BE>, may be absent 424 * LE - Little endian, BE - Big endian 425 */ 426 #define XENSND_PCM_FORMAT_S8 0 427 #define XENSND_PCM_FORMAT_U8 1 428 #define XENSND_PCM_FORMAT_S16_LE 2 429 #define XENSND_PCM_FORMAT_S16_BE 3 430 #define XENSND_PCM_FORMAT_U16_LE 4 431 #define XENSND_PCM_FORMAT_U16_BE 5 432 #define XENSND_PCM_FORMAT_S24_LE 6 433 #define XENSND_PCM_FORMAT_S24_BE 7 434 #define XENSND_PCM_FORMAT_U24_LE 8 435 #define XENSND_PCM_FORMAT_U24_BE 9 436 #define XENSND_PCM_FORMAT_S32_LE 10 437 #define XENSND_PCM_FORMAT_S32_BE 11 438 #define XENSND_PCM_FORMAT_U32_LE 12 439 #define XENSND_PCM_FORMAT_U32_BE 13 440 #define XENSND_PCM_FORMAT_F32_LE 14 /* 4-byte float, IEEE-754 32-bit, */ 441 #define XENSND_PCM_FORMAT_F32_BE 15 /* range -1.0 to 1.0 */ 442 #define XENSND_PCM_FORMAT_F64_LE 16 /* 8-byte float, IEEE-754 64-bit, */ 443 #define XENSND_PCM_FORMAT_F64_BE 17 /* range -1.0 to 1.0 */ 444 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE 18 445 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE 19 446 #define XENSND_PCM_FORMAT_MU_LAW 20 447 #define XENSND_PCM_FORMAT_A_LAW 21 448 #define XENSND_PCM_FORMAT_IMA_ADPCM 22 449 #define XENSND_PCM_FORMAT_MPEG 23 450 #define XENSND_PCM_FORMAT_GSM 24 451 452 /* 453 ****************************************************************************** 454 * REQUEST CODES 455 ****************************************************************************** 456 */ 457 #define XENSND_OP_OPEN 0 458 #define XENSND_OP_CLOSE 1 459 #define XENSND_OP_READ 2 460 #define XENSND_OP_WRITE 3 461 #define XENSND_OP_SET_VOLUME 4 462 #define XENSND_OP_GET_VOLUME 5 463 #define XENSND_OP_MUTE 6 464 #define XENSND_OP_UNMUTE 7 465 #define XENSND_OP_TRIGGER 8 466 #define XENSND_OP_HW_PARAM_QUERY 9 467 468 #define XENSND_OP_TRIGGER_START 0 469 #define XENSND_OP_TRIGGER_PAUSE 1 470 #define XENSND_OP_TRIGGER_STOP 2 471 #define XENSND_OP_TRIGGER_RESUME 3 472 473 /* 474 ****************************************************************************** 475 * EVENT CODES 476 ****************************************************************************** 477 */ 478 #define XENSND_EVT_CUR_POS 0 479 480 /* 481 ****************************************************************************** 482 * XENSTORE FIELD AND PATH NAME STRINGS, HELPERS 483 ****************************************************************************** 484 */ 485 #define XENSND_DRIVER_NAME "vsnd" 486 487 #define XENSND_LIST_SEPARATOR "," 488 /* Field names */ 489 #define XENSND_FIELD_BE_VERSIONS "versions" 490 #define XENSND_FIELD_FE_VERSION "version" 491 #define XENSND_FIELD_VCARD_SHORT_NAME "short-name" 492 #define XENSND_FIELD_VCARD_LONG_NAME "long-name" 493 #define XENSND_FIELD_RING_REF "ring-ref" 494 #define XENSND_FIELD_EVT_CHNL "event-channel" 495 #define XENSND_FIELD_EVT_RING_REF "evt-ring-ref" 496 #define XENSND_FIELD_EVT_EVT_CHNL "evt-event-channel" 497 #define XENSND_FIELD_DEVICE_NAME "name" 498 #define XENSND_FIELD_TYPE "type" 499 #define XENSND_FIELD_STREAM_UNIQUE_ID "unique-id" 500 #define XENSND_FIELD_CHANNELS_MIN "channels-min" 501 #define XENSND_FIELD_CHANNELS_MAX "channels-max" 502 #define XENSND_FIELD_SAMPLE_RATES "sample-rates" 503 #define XENSND_FIELD_SAMPLE_FORMATS "sample-formats" 504 #define XENSND_FIELD_BUFFER_SIZE "buffer-size" 505 506 /* Stream type field values. */ 507 #define XENSND_STREAM_TYPE_PLAYBACK "p" 508 #define XENSND_STREAM_TYPE_CAPTURE "c" 509 /* Sample rate max string length */ 510 #define XENSND_SAMPLE_RATE_MAX_LEN 11 511 /* Sample format field values */ 512 #define XENSND_SAMPLE_FORMAT_MAX_LEN 24 513 514 #define XENSND_PCM_FORMAT_S8_STR "s8" 515 #define XENSND_PCM_FORMAT_U8_STR "u8" 516 #define XENSND_PCM_FORMAT_S16_LE_STR "s16_le" 517 #define XENSND_PCM_FORMAT_S16_BE_STR "s16_be" 518 #define XENSND_PCM_FORMAT_U16_LE_STR "u16_le" 519 #define XENSND_PCM_FORMAT_U16_BE_STR "u16_be" 520 #define XENSND_PCM_FORMAT_S24_LE_STR "s24_le" 521 #define XENSND_PCM_FORMAT_S24_BE_STR "s24_be" 522 #define XENSND_PCM_FORMAT_U24_LE_STR "u24_le" 523 #define XENSND_PCM_FORMAT_U24_BE_STR "u24_be" 524 #define XENSND_PCM_FORMAT_S32_LE_STR "s32_le" 525 #define XENSND_PCM_FORMAT_S32_BE_STR "s32_be" 526 #define XENSND_PCM_FORMAT_U32_LE_STR "u32_le" 527 #define XENSND_PCM_FORMAT_U32_BE_STR "u32_be" 528 #define XENSND_PCM_FORMAT_F32_LE_STR "float_le" 529 #define XENSND_PCM_FORMAT_F32_BE_STR "float_be" 530 #define XENSND_PCM_FORMAT_F64_LE_STR "float64_le" 531 #define XENSND_PCM_FORMAT_F64_BE_STR "float64_be" 532 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE_STR "iec958_subframe_le" 533 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE_STR "iec958_subframe_be" 534 #define XENSND_PCM_FORMAT_MU_LAW_STR "mu_law" 535 #define XENSND_PCM_FORMAT_A_LAW_STR "a_law" 536 #define XENSND_PCM_FORMAT_IMA_ADPCM_STR "ima_adpcm" 537 #define XENSND_PCM_FORMAT_MPEG_STR "mpeg" 538 #define XENSND_PCM_FORMAT_GSM_STR "gsm" 539 540 541 /* 542 ****************************************************************************** 543 * STATUS RETURN CODES 544 ****************************************************************************** 545 * 546 * Status return code is zero on success and -XEN_EXX on failure. 547 * 548 ****************************************************************************** 549 * Assumptions 550 ****************************************************************************** 551 * o usage of grant reference 0 as invalid grant reference: 552 * grant reference 0 is valid, but never exposed to a PV driver, 553 * because of the fact it is already in use/reserved by the PV console. 554 * o all references in this document to page sizes must be treated 555 * as pages of size XEN_PAGE_SIZE unless otherwise noted. 556 * 557 ****************************************************************************** 558 * Description of the protocol between frontend and backend driver 559 ****************************************************************************** 560 * 561 * The two halves of a Para-virtual sound driver communicate with 562 * each other using shared pages and event channels. 563 * Shared page contains a ring with request/response packets. 564 * 565 * Packets, used for input/output operations, e.g. read/write, set/get volume, 566 * etc., provide offset/length fields in order to allow asynchronous protocol 567 * operation with buffer space sharing: part of the buffer allocated at 568 * XENSND_OP_OPEN can be used for audio samples and part, for example, 569 * for volume control. 570 * 571 * All reserved fields in the structures below must be 0. 572 * 573 *---------------------------------- Requests --------------------------------- 574 * 575 * All request packets have the same length (64 octets) 576 * All request packets have common header: 577 * 0 1 2 3 octet 578 * +----------------+----------------+----------------+----------------+ 579 * | id | operation | reserved | 4 580 * +----------------+----------------+----------------+----------------+ 581 * | reserved | 8 582 * +----------------+----------------+----------------+----------------+ 583 * id - uint16_t, private guest value, echoed in response 584 * operation - uint8_t, operation code, XENSND_OP_??? 585 * 586 * For all packets which use offset and length: 587 * offset - uint32_t, read or write data offset within the shared buffer, 588 * passed with XENSND_OP_OPEN request, octets, 589 * [0; XENSND_OP_OPEN.buffer_sz - 1]. 590 * length - uint32_t, read or write data length, octets 591 * 592 * Request open - open a PCM stream for playback or capture: 593 * 594 * 0 1 2 3 octet 595 * +----------------+----------------+----------------+----------------+ 596 * | id | XENSND_OP_OPEN | reserved | 4 597 * +----------------+----------------+----------------+----------------+ 598 * | reserved | 8 599 * +----------------+----------------+----------------+----------------+ 600 * | pcm_rate | 12 601 * +----------------+----------------+----------------+----------------+ 602 * | pcm_format | pcm_channels | reserved | 16 603 * +----------------+----------------+----------------+----------------+ 604 * | buffer_sz | 20 605 * +----------------+----------------+----------------+----------------+ 606 * | gref_directory | 24 607 * +----------------+----------------+----------------+----------------+ 608 * | period_sz | 28 609 * +----------------+----------------+----------------+----------------+ 610 * | reserved | 32 611 * +----------------+----------------+----------------+----------------+ 612 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 613 * +----------------+----------------+----------------+----------------+ 614 * | reserved | 64 615 * +----------------+----------------+----------------+----------------+ 616 * 617 * pcm_rate - uint32_t, stream data rate, Hz 618 * pcm_format - uint8_t, XENSND_PCM_FORMAT_XXX value 619 * pcm_channels - uint8_t, number of channels of this stream, 620 * [channels-min; channels-max] 621 * buffer_sz - uint32_t, buffer size to be allocated, octets 622 * period_sz - uint32_t, event period size, octets 623 * This is the requested value of the period at which frontend would 624 * like to receive XENSND_EVT_CUR_POS notifications from the backend when 625 * stream position advances during playback/capture. 626 * It shows how many octets are expected to be played/captured before 627 * sending such an event. 628 * If set to 0 no XENSND_EVT_CUR_POS events are sent by the backend. 629 * 630 * gref_directory - grant_ref_t, a reference to the first shared page 631 * describing shared buffer references. At least one page exists. If shared 632 * buffer size (buffer_sz) exceeds what can be addressed by this single page, 633 * then reference to the next page must be supplied (see gref_dir_next_page 634 * below) 635 */ 636 637 struct xensnd_open_req { 638 uint32_t pcm_rate; 639 uint8_t pcm_format; 640 uint8_t pcm_channels; 641 uint16_t reserved; 642 uint32_t buffer_sz; 643 grant_ref_t gref_directory; 644 uint32_t period_sz; 645 }; 646 647 /* 648 * Shared page for XENSND_OP_OPEN buffer descriptor (gref_directory in the 649 * request) employs a list of pages, describing all pages of the shared data 650 * buffer: 651 * 0 1 2 3 octet 652 * +----------------+----------------+----------------+----------------+ 653 * | gref_dir_next_page | 4 654 * +----------------+----------------+----------------+----------------+ 655 * | gref[0] | 8 656 * +----------------+----------------+----------------+----------------+ 657 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 658 * +----------------+----------------+----------------+----------------+ 659 * | gref[i] | i*4+8 660 * +----------------+----------------+----------------+----------------+ 661 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 662 * +----------------+----------------+----------------+----------------+ 663 * | gref[N - 1] | N*4+8 664 * +----------------+----------------+----------------+----------------+ 665 * 666 * gref_dir_next_page - grant_ref_t, reference to the next page describing 667 * page directory. Must be 0 if there are no more pages in the list. 668 * gref[i] - grant_ref_t, reference to a shared page of the buffer 669 * allocated at XENSND_OP_OPEN 670 * 671 * Number of grant_ref_t entries in the whole page directory is not 672 * passed, but instead can be calculated as: 673 * num_grefs_total = (XENSND_OP_OPEN.buffer_sz + XEN_PAGE_SIZE - 1) / 674 * XEN_PAGE_SIZE 675 */ 676 677 struct xensnd_page_directory { 678 grant_ref_t gref_dir_next_page; 679 grant_ref_t gref[1]; /* Variable length */ 680 }; 681 682 /* 683 * Request close - close an opened pcm stream: 684 * 0 1 2 3 octet 685 * +----------------+----------------+----------------+----------------+ 686 * | id | XENSND_OP_CLOSE| reserved | 4 687 * +----------------+----------------+----------------+----------------+ 688 * | reserved | 8 689 * +----------------+----------------+----------------+----------------+ 690 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 691 * +----------------+----------------+----------------+----------------+ 692 * | reserved | 64 693 * +----------------+----------------+----------------+----------------+ 694 * 695 * Request read/write - used for read (for capture) or write (for playback): 696 * 0 1 2 3 octet 697 * +----------------+----------------+----------------+----------------+ 698 * | id | operation | reserved | 4 699 * +----------------+----------------+----------------+----------------+ 700 * | reserved | 8 701 * +----------------+----------------+----------------+----------------+ 702 * | offset | 12 703 * +----------------+----------------+----------------+----------------+ 704 * | length | 16 705 * +----------------+----------------+----------------+----------------+ 706 * | reserved | 20 707 * +----------------+----------------+----------------+----------------+ 708 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 709 * +----------------+----------------+----------------+----------------+ 710 * | reserved | 64 711 * +----------------+----------------+----------------+----------------+ 712 * 713 * operation - XENSND_OP_READ for read or XENSND_OP_WRITE for write 714 */ 715 716 struct xensnd_rw_req { 717 uint32_t offset; 718 uint32_t length; 719 }; 720 721 /* 722 * Request set/get volume - set/get channels' volume of the stream given: 723 * 0 1 2 3 octet 724 * +----------------+----------------+----------------+----------------+ 725 * | id | operation | reserved | 4 726 * +----------------+----------------+----------------+----------------+ 727 * | reserved | 8 728 * +----------------+----------------+----------------+----------------+ 729 * | offset | 12 730 * +----------------+----------------+----------------+----------------+ 731 * | length | 16 732 * +----------------+----------------+----------------+----------------+ 733 * | reserved | 20 734 * +----------------+----------------+----------------+----------------+ 735 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 736 * +----------------+----------------+----------------+----------------+ 737 * | reserved | 64 738 * +----------------+----------------+----------------+----------------+ 739 * 740 * operation - XENSND_OP_SET_VOLUME for volume set 741 * or XENSND_OP_GET_VOLUME for volume get 742 * Buffer passed with XENSND_OP_OPEN is used to exchange volume 743 * values: 744 * 745 * 0 1 2 3 octet 746 * +----------------+----------------+----------------+----------------+ 747 * | channel[0] | 4 748 * +----------------+----------------+----------------+----------------+ 749 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 750 * +----------------+----------------+----------------+----------------+ 751 * | channel[i] | i*4 752 * +----------------+----------------+----------------+----------------+ 753 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 754 * +----------------+----------------+----------------+----------------+ 755 * | channel[N - 1] | (N-1)*4 756 * +----------------+----------------+----------------+----------------+ 757 * 758 * N = XENSND_OP_OPEN.pcm_channels 759 * i - uint8_t, index of a channel 760 * channel[i] - sint32_t, volume of i-th channel 761 * Volume is expressed as a signed value in steps of 0.001 dB, 762 * while 0 being 0 dB. 763 * 764 * Request mute/unmute - mute/unmute stream: 765 * 0 1 2 3 octet 766 * +----------------+----------------+----------------+----------------+ 767 * | id | operation | reserved | 4 768 * +----------------+----------------+----------------+----------------+ 769 * | reserved | 8 770 * +----------------+----------------+----------------+----------------+ 771 * | offset | 12 772 * +----------------+----------------+----------------+----------------+ 773 * | length | 16 774 * +----------------+----------------+----------------+----------------+ 775 * | reserved | 20 776 * +----------------+----------------+----------------+----------------+ 777 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 778 * +----------------+----------------+----------------+----------------+ 779 * | reserved | 64 780 * +----------------+----------------+----------------+----------------+ 781 * 782 * operation - XENSND_OP_MUTE for mute or XENSND_OP_UNMUTE for unmute 783 * Buffer passed with XENSND_OP_OPEN is used to exchange mute/unmute 784 * values: 785 * 786 * 0 octet 787 * +----------------+----------------+----------------+----------------+ 788 * | channel[0] | 4 789 * +----------------+----------------+----------------+----------------+ 790 * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 791 * +----------------+----------------+----------------+----------------+ 792 * | channel[i] | i*4 793 * +----------------+----------------+----------------+----------------+ 794 * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 795 * +----------------+----------------+----------------+----------------+ 796 * | channel[N - 1] | (N-1)*4 797 * +----------------+----------------+----------------+----------------+ 798 * 799 * N = XENSND_OP_OPEN.pcm_channels 800 * i - uint8_t, index of a channel 801 * channel[i] - uint8_t, non-zero if i-th channel needs to be muted/unmuted 802 * 803 *------------------------------------ N.B. ----------------------------------- 804 * 805 * The 'struct xensnd_rw_req' is also used for XENSND_OP_SET_VOLUME, 806 * XENSND_OP_GET_VOLUME, XENSND_OP_MUTE, XENSND_OP_UNMUTE. 807 * 808 * Request stream running state change - trigger PCM stream running state 809 * to start, stop, pause or resume: 810 * 811 * 0 1 2 3 octet 812 * +----------------+----------------+----------------+----------------+ 813 * | id | _OP_TRIGGER | reserved | 4 814 * +----------------+----------------+----------------+----------------+ 815 * | reserved | 8 816 * +----------------+----------------+----------------+----------------+ 817 * | type | reserved | 12 818 * +----------------+----------------+----------------+----------------+ 819 * | reserved | 16 820 * +----------------+----------------+----------------+----------------+ 821 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 822 * +----------------+----------------+----------------+----------------+ 823 * | reserved | 64 824 * +----------------+----------------+----------------+----------------+ 825 * 826 * type - uint8_t, XENSND_OP_TRIGGER_XXX value 827 */ 828 829 struct xensnd_trigger_req { 830 uint8_t type; 831 }; 832 833 /* 834 * Request stream parameter ranges: request intervals and 835 * masks of supported ranges for stream configuration values. 836 * 837 * Sound device configuration for a particular stream is a limited subset 838 * of the multidimensional configuration available on XenStore, e.g. 839 * once the frame rate has been selected there is a limited supported range 840 * for sample rates becomes available (which might be the same set configured 841 * on XenStore or less). For example, selecting 96kHz sample rate may limit 842 * number of channels available for such configuration from 4 to 2, etc. 843 * Thus, each call to XENSND_OP_HW_PARAM_QUERY may reduce configuration 844 * space making it possible to iteratively get the final stream configuration, 845 * used in XENSND_OP_OPEN request. 846 * 847 * See response format for this request. 848 * 849 * 0 1 2 3 octet 850 * +----------------+----------------+----------------+----------------+ 851 * | id | _HW_PARAM_QUERY| reserved | 4 852 * +----------------+----------------+----------------+----------------+ 853 * | reserved | 8 854 * +----------------+----------------+----------------+----------------+ 855 * | formats mask low 32-bit | 12 856 * +----------------+----------------+----------------+----------------+ 857 * | formats mask high 32-bit | 16 858 * +----------------+----------------+----------------+----------------+ 859 * | min rate | 20 860 * +----------------+----------------+----------------+----------------+ 861 * | max rate | 24 862 * +----------------+----------------+----------------+----------------+ 863 * | min channels | 28 864 * +----------------+----------------+----------------+----------------+ 865 * | max channels | 32 866 * +----------------+----------------+----------------+----------------+ 867 * | min buffer frames | 36 868 * +----------------+----------------+----------------+----------------+ 869 * | max buffer frames | 40 870 * +----------------+----------------+----------------+----------------+ 871 * | min period frames | 44 872 * +----------------+----------------+----------------+----------------+ 873 * | max period frames | 48 874 * +----------------+----------------+----------------+----------------+ 875 * | reserved | 52 876 * +----------------+----------------+----------------+----------------+ 877 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 878 * +----------------+----------------+----------------+----------------+ 879 * | reserved | 64 880 * +----------------+----------------+----------------+----------------+ 881 * 882 * formats - uint64_t, bit mask representing values of the parameter 883 * made as bitwise OR of (1 << XENSND_PCM_FORMAT_XXX) values 884 * 885 * For interval parameters: 886 * min - uint32_t, minimum value of the parameter 887 * max - uint32_t, maximum value of the parameter 888 * 889 * Frame is defined as a product of the number of channels by the 890 * number of octets per one sample. 891 */ 892 893 struct xensnd_query_hw_param { 894 uint64_t formats; 895 struct { 896 uint32_t min; 897 uint32_t max; 898 } rates; 899 struct { 900 uint32_t min; 901 uint32_t max; 902 } channels; 903 struct { 904 uint32_t min; 905 uint32_t max; 906 } buffer; 907 struct { 908 uint32_t min; 909 uint32_t max; 910 } period; 911 }; 912 913 /* 914 *---------------------------------- Responses -------------------------------- 915 * 916 * All response packets have the same length (64 octets) 917 * 918 * All response packets have common header: 919 * 0 1 2 3 octet 920 * +----------------+----------------+----------------+----------------+ 921 * | id | operation | reserved | 4 922 * +----------------+----------------+----------------+----------------+ 923 * | status | 8 924 * +----------------+----------------+----------------+----------------+ 925 * 926 * id - uint16_t, copied from the request 927 * operation - uint8_t, XENSND_OP_* - copied from request 928 * status - int32_t, response status, zero on success and -XEN_EXX on failure 929 * 930 * 931 * HW parameter query response - response for XENSND_OP_HW_PARAM_QUERY: 932 * 0 1 2 3 octet 933 * +----------------+----------------+----------------+----------------+ 934 * | id | operation | reserved | 4 935 * +----------------+----------------+----------------+----------------+ 936 * | status | 8 937 * +----------------+----------------+----------------+----------------+ 938 * | formats mask low 32-bit | 12 939 * +----------------+----------------+----------------+----------------+ 940 * | formats mask high 32-bit | 16 941 * +----------------+----------------+----------------+----------------+ 942 * | min rate | 20 943 * +----------------+----------------+----------------+----------------+ 944 * | max rate | 24 945 * +----------------+----------------+----------------+----------------+ 946 * | min channels | 28 947 * +----------------+----------------+----------------+----------------+ 948 * | max channels | 32 949 * +----------------+----------------+----------------+----------------+ 950 * | min buffer frames | 36 951 * +----------------+----------------+----------------+----------------+ 952 * | max buffer frames | 40 953 * +----------------+----------------+----------------+----------------+ 954 * | min period frames | 44 955 * +----------------+----------------+----------------+----------------+ 956 * | max period frames | 48 957 * +----------------+----------------+----------------+----------------+ 958 * | reserved | 52 959 * +----------------+----------------+----------------+----------------+ 960 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 961 * +----------------+----------------+----------------+----------------+ 962 * | reserved | 64 963 * +----------------+----------------+----------------+----------------+ 964 * 965 * Meaning of the values in this response is the same as for 966 * XENSND_OP_HW_PARAM_QUERY request. 967 */ 968 969 /* 970 *----------------------------------- Events ---------------------------------- 971 * 972 * Events are sent via shared page allocated by the front and propagated by 973 * evt-event-channel/evt-ring-ref XenStore entries 974 * All event packets have the same length (64 octets) 975 * All event packets have common header: 976 * 0 1 2 3 octet 977 * +----------------+----------------+----------------+----------------+ 978 * | id | type | reserved | 4 979 * +----------------+----------------+----------------+----------------+ 980 * | reserved | 8 981 * +----------------+----------------+----------------+----------------+ 982 * 983 * id - uint16_t, event id, may be used by front 984 * type - uint8_t, type of the event 985 * 986 * 987 * Current stream position - event from back to front when stream's 988 * playback/capture position has advanced: 989 * 0 1 2 3 octet 990 * +----------------+----------------+----------------+----------------+ 991 * | id | _EVT_CUR_POS | reserved | 4 992 * +----------------+----------------+----------------+----------------+ 993 * | reserved | 8 994 * +----------------+----------------+----------------+----------------+ 995 * | position low 32-bit | 12 996 * +----------------+----------------+----------------+----------------+ 997 * | position high 32-bit | 16 998 * +----------------+----------------+----------------+----------------+ 999 * | reserved | 20 1000 * +----------------+----------------+----------------+----------------+ 1001 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 1002 * +----------------+----------------+----------------+----------------+ 1003 * | reserved | 64 1004 * +----------------+----------------+----------------+----------------+ 1005 * 1006 * position - current value of stream's playback/capture position, octets 1007 * 1008 */ 1009 1010 struct xensnd_cur_pos_evt { 1011 uint64_t position; 1012 }; 1013 1014 struct xensnd_req { 1015 uint16_t id; 1016 uint8_t operation; 1017 uint8_t reserved[5]; 1018 union { 1019 struct xensnd_open_req open; 1020 struct xensnd_rw_req rw; 1021 struct xensnd_trigger_req trigger; 1022 struct xensnd_query_hw_param hw_param; 1023 uint8_t reserved[56]; 1024 } op; 1025 }; 1026 1027 struct xensnd_resp { 1028 uint16_t id; 1029 uint8_t operation; 1030 uint8_t reserved; 1031 int32_t status; 1032 union { 1033 struct xensnd_query_hw_param hw_param; 1034 uint8_t reserved1[56]; 1035 } resp; 1036 }; 1037 1038 struct xensnd_evt { 1039 uint16_t id; 1040 uint8_t type; 1041 uint8_t reserved[5]; 1042 union { 1043 struct xensnd_cur_pos_evt cur_pos; 1044 uint8_t reserved[56]; 1045 } op; 1046 }; 1047 1048 DEFINE_RING_TYPES(xen_sndif, struct xensnd_req, struct xensnd_resp); 1049 1050 /* 1051 ****************************************************************************** 1052 * Back to front events delivery 1053 ****************************************************************************** 1054 * In order to deliver asynchronous events from back to front a shared page is 1055 * allocated by front and its granted reference propagated to back via 1056 * XenStore entries (evt-ring-ref/evt-event-channel). 1057 * This page has a common header used by both front and back to synchronize 1058 * access and control event's ring buffer, while back being a producer of the 1059 * events and front being a consumer. The rest of the page after the header 1060 * is used for event packets. 1061 * 1062 * Upon reception of an event(s) front may confirm its reception 1063 * for either each event, group of events or none. 1064 */ 1065 1066 struct xensnd_event_page { 1067 uint32_t in_cons; 1068 uint32_t in_prod; 1069 uint8_t reserved[56]; 1070 }; 1071 1072 #define XENSND_EVENT_PAGE_SIZE XEN_PAGE_SIZE 1073 #define XENSND_IN_RING_OFFS (sizeof(struct xensnd_event_page)) 1074 #define XENSND_IN_RING_SIZE (XENSND_EVENT_PAGE_SIZE - XENSND_IN_RING_OFFS) 1075 #define XENSND_IN_RING_LEN (XENSND_IN_RING_SIZE / sizeof(struct xensnd_evt)) 1076 #define XENSND_IN_RING(page) \ 1077 ((struct xensnd_evt *)((char *)(page) + XENSND_IN_RING_OFFS)) 1078 #define XENSND_IN_RING_REF(page, idx) \ 1079 (XENSND_IN_RING((page))[(idx) % XENSND_IN_RING_LEN]) 1080 1081 #endif /* __XEN_PUBLIC_IO_SNDIF_H__ */ 1082