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 * Feature and Parameter Negotiation 42 ****************************************************************************** 43 * 44 * Front->back notifications: when enqueuing a new request, sending a 45 * notification can be made conditional on xensnd_req (i.e., the generic 46 * hold-off mechanism provided by the ring macros). Backends must set 47 * xensnd_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()). 48 * 49 * Back->front notifications: when enqueuing a new response, sending a 50 * notification can be made conditional on xensnd_resp (i.e., the generic 51 * hold-off mechanism provided by the ring macros). Frontends must set 52 * xensnd_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()). 53 * 54 * The two halves of a para-virtual sound card driver utilize nodes within 55 * XenStore to communicate capabilities and to negotiate operating parameters. 56 * This section enumerates these nodes which reside in the respective front and 57 * backend portions of XenStore, following the XenBus convention. 58 * 59 * All data in XenStore is stored as strings. Nodes specifying numeric 60 * values are encoded in decimal. Integer value ranges listed below are 61 * expressed as fixed sized integer types capable of storing the conversion 62 * of a properly formated node string, without loss of information. 63 * 64 ****************************************************************************** 65 * Example configuration 66 ****************************************************************************** 67 * 68 * Note: depending on the use-case backend can expose more sound cards and 69 * PCM devices/streams than the underlying HW physically has by employing 70 * SW mixers, configuring virtual sound streams, channels etc. 71 * 72 * This is an example of backend and frontend configuration: 73 * 74 *--------------------------------- Backend ----------------------------------- 75 * 76 * /local/domain/0/backend/vsnd/1/0/frontend-id = "1" 77 * /local/domain/0/backend/vsnd/1/0/frontend = "/local/domain/1/device/vsnd/0" 78 * /local/domain/0/backend/vsnd/1/0/state = "4" 79 * /local/domain/0/backend/vsnd/1/0/versions = "1,2" 80 * 81 *--------------------------------- Frontend ---------------------------------- 82 * 83 * /local/domain/1/device/vsnd/0/backend-id = "0" 84 * /local/domain/1/device/vsnd/0/backend = "/local/domain/0/backend/vsnd/1/0" 85 * /local/domain/1/device/vsnd/0/state = "4" 86 * /local/domain/1/device/vsnd/0/version = "1" 87 * 88 *----------------------------- Card configuration ---------------------------- 89 * 90 * /local/domain/1/device/vsnd/0/short-name = "Card short name" 91 * /local/domain/1/device/vsnd/0/long-name = "Card long name" 92 * /local/domain/1/device/vsnd/0/sample-rates = "8000,32000,44100,48000,96000" 93 * /local/domain/1/device/vsnd/0/sample-formats = "s8,u8,s16_le,s16_be" 94 * /local/domain/1/device/vsnd/0/buffer-size = "262144" 95 * 96 *------------------------------- PCM device 0 -------------------------------- 97 * 98 * /local/domain/1/device/vsnd/0/0/name = "General analog" 99 * /local/domain/1/device/vsnd/0/0/channels-max = "5" 100 * 101 *----------------------------- Stream 0, playback ---------------------------- 102 * 103 * /local/domain/1/device/vsnd/0/0/0/type = "p" 104 * /local/domain/1/device/vsnd/0/0/0/sample-formats = "s8,u8" 105 * /local/domain/1/device/vsnd/0/0/0/unique-id = "0" 106 * 107 * /local/domain/1/device/vsnd/0/0/0/ring-ref = "386" 108 * /local/domain/1/device/vsnd/0/0/0/event-channel = "15" 109 * 110 *------------------------------ Stream 1, capture ---------------------------- 111 * 112 * /local/domain/1/device/vsnd/0/0/1/type = "c" 113 * /local/domain/1/device/vsnd/0/0/1/channels-max = "2" 114 * /local/domain/1/device/vsnd/0/0/1/unique-id = "1" 115 * 116 * /local/domain/1/device/vsnd/0/0/1/ring-ref = "384" 117 * /local/domain/1/device/vsnd/0/0/1/event-channel = "13" 118 * 119 *------------------------------- PCM device 1 -------------------------------- 120 * 121 * /local/domain/1/device/vsnd/0/1/name = "HDMI-0" 122 * /local/domain/1/device/vsnd/0/1/sample-rates = "8000,32000,44100" 123 * 124 *------------------------------ Stream 0, capture ---------------------------- 125 * 126 * /local/domain/1/device/vsnd/0/1/0/type = "c" 127 * /local/domain/1/device/vsnd/0/1/0/unique-id = "2" 128 * 129 * /local/domain/1/device/vsnd/0/1/0/ring-ref = "387" 130 * /local/domain/1/device/vsnd/0/1/0/event-channel = "151" 131 * 132 *------------------------------- PCM device 2 -------------------------------- 133 * 134 * /local/domain/1/device/vsnd/0/2/name = "SPDIF" 135 * 136 *----------------------------- Stream 0, playback ---------------------------- 137 * 138 * /local/domain/1/device/vsnd/0/2/0/type = "p" 139 * /local/domain/1/device/vsnd/0/2/0/unique-id = "3" 140 * 141 * /local/domain/1/device/vsnd/0/2/0/ring-ref = "389" 142 * /local/domain/1/device/vsnd/0/2/0/event-channel = "152" 143 * 144 ****************************************************************************** 145 * Backend XenBus Nodes 146 ****************************************************************************** 147 * 148 *----------------------------- Protocol version ------------------------------ 149 * 150 * versions 151 * Values: <string> 152 * 153 * List of XENSND_LIST_SEPARATOR separated protocol versions supported 154 * by the backend. For example "1,2,3". 155 * 156 ****************************************************************************** 157 * Frontend XenBus Nodes 158 ****************************************************************************** 159 * 160 *-------------------------------- Addressing --------------------------------- 161 * 162 * dom-id 163 * Values: <uint16_t> 164 * 165 * Domain identifier. 166 * 167 * dev-id 168 * Values: <uint16_t> 169 * 170 * Device identifier. 171 * 172 * pcm-dev-idx 173 * Values: <uint8_t> 174 * 175 * Zero based contigous index of the PCM device. 176 * 177 * stream-idx 178 * Values: <uint8_t> 179 * 180 * Zero based contigous index of the stream of the PCM device. 181 * 182 * The following pattern is used for addressing: 183 * /local/domain/<dom-id>/device/vsnd/<dev-id>/<pcm-dev-idx>/<stream-idx>/... 184 * 185 *----------------------------- Protocol version ------------------------------ 186 * 187 * version 188 * Values: <string> 189 * 190 * Protocol version, chosen among the ones supported by the backend. 191 * 192 *------------------------------- PCM settings -------------------------------- 193 * 194 * Every virtualized sound frontend has a set of PCM devices and streams, each 195 * could be individually configured. Part of the PCM configuration can be 196 * defined at higher level of the hierarchy and be fully or partially re-used 197 * by the underlying layers. These configuration values are: 198 * o number of channels (min/max) 199 * o supported sample rates 200 * o supported sample formats. 201 * E.g. one can define these values for the whole card, device or stream. 202 * Every underlying layer in turn can re-define some or all of them to better 203 * fit its needs. For example, card may define number of channels to be 204 * in [1; 8] range, and some particular stream may be limited to [1; 2] only. 205 * The rule is that the underlying layer must be a subset of the upper layer 206 * range. 207 * 208 * channels-min 209 * Values: <uint8_t> 210 * 211 * The minimum amount of channels that is supported, [1; channels-max]. 212 * Optional, if not set or omitted a value of 1 is used. 213 * 214 * channels-max 215 * Values: <uint8_t> 216 * 217 * The maximum amount of channels that is supported. 218 * Must be at least <channels-min>. 219 * 220 * sample-rates 221 * Values: <list of uint32_t> 222 * 223 * List of supported sample rates separated by XENSND_LIST_SEPARATOR. 224 * Sample rates are expressed as a list of decimal values w/o any 225 * ordering requirement. 226 * 227 * sample-formats 228 * Values: <list of XENSND_PCM_FORMAT_XXX_STR> 229 * 230 * List of supported sample formats separated by XENSND_LIST_SEPARATOR. 231 * Items must not exceed XENSND_SAMPLE_FORMAT_MAX_LEN length. 232 * 233 * buffer-size 234 * Values: <uint32_t> 235 * 236 * The maximum size in octets of the buffer to allocate per stream. 237 * 238 *----------------------- Virtual sound card settings ------------------------- 239 * short-name 240 * Values: <char[32]> 241 * 242 * Short name of the virtual sound card. Optional. 243 * 244 * long-name 245 * Values: <char[80]> 246 * 247 * Long name of the virtual sound card. Optional. 248 * 249 *----------------------------- Device settings ------------------------------- 250 * name 251 * Values: <char[80]> 252 * 253 * Name of the sound device within the virtual sound card. Optional. 254 * 255 *----------------------------- Stream settings ------------------------------- 256 * 257 * type 258 * Values: "p", "c" 259 * 260 * Stream type: "p" - playback stream, "c" - capture stream 261 * 262 * If both capture and playback are needed then two streams need to be 263 * defined under the same device. 264 * 265 * unique-id 266 * Values: <uint32_t> 267 * 268 * After stream initialization it is assigned a unique ID (within the front 269 * driver), so every stream of the frontend can be identified by the 270 * backend by this ID. This is not equal to stream-idx as the later is 271 * zero based within the device, but this index is contigous within the 272 * driver. 273 * 274 *-------------------- Stream Request Transport Parameters -------------------- 275 * 276 * event-channel 277 * Values: <uint32_t> 278 * 279 * The identifier of the Xen event channel used to signal activity 280 * in the ring buffer. 281 * 282 * ring-ref 283 * Values: <uint32_t> 284 * 285 * The Xen grant reference granting permission for the backend to map 286 * a sole page in a single page sized ring buffer. 287 * 288 ****************************************************************************** 289 * STATE DIAGRAMS 290 ****************************************************************************** 291 * 292 * Tool stack creates front and back state nodes with initial state 293 * XenbusStateInitialising. 294 * Tool stack creates and sets up frontend sound configuration nodes per domain. 295 * 296 * Front Back 297 * ================================= ===================================== 298 * XenbusStateInitialising XenbusStateInitialising 299 * o Query backend device identification 300 * data. 301 * o Open and validate backend device. 302 * | 303 * | 304 * V 305 * XenbusStateInitWait 306 * 307 * o Query frontend configuration 308 * o Allocate and initialize 309 * event channels per configured 310 * playback/capture stream. 311 * o Publish transport parameters 312 * that will be in effect during 313 * this connection. 314 * | 315 * | 316 * V 317 * XenbusStateInitialised 318 * 319 * o Query frontend transport parameters. 320 * o Connect to the event channels. 321 * | 322 * | 323 * V 324 * XenbusStateConnected 325 * 326 * o Create and initialize OS 327 * virtual sound device instances 328 * as per configuration. 329 * | 330 * | 331 * V 332 * XenbusStateConnected 333 * 334 * XenbusStateUnknown 335 * XenbusStateClosed 336 * XenbusStateClosing 337 * o Remove virtual sound device 338 * o Remove event channels 339 * | 340 * | 341 * V 342 * XenbusStateClosed 343 * 344 *------------------------------- Recovery flow ------------------------------- 345 * 346 * In case of frontend unrecoverable errors backend handles that as 347 * if frontend goes into the XenbusStateClosed state. 348 * 349 * In case of backend unrecoverable errors frontend tries removing 350 * the virtualized device. If this is possible at the moment of error, 351 * then frontend goes into the XenbusStateInitialising state and is ready for 352 * new connection with backend. If the virtualized device is still in use and 353 * cannot be removed, then frontend goes into the XenbusStateReconfiguring state 354 * until either the virtualized device removed or backend initiates a new 355 * connection. On the virtualized device removal frontend goes into the 356 * XenbusStateInitialising state. 357 * 358 * Note on XenbusStateReconfiguring state of the frontend: if backend has 359 * unrecoverable errors then frontend cannot send requests to the backend 360 * and thus cannot provide functionality of the virtualized device anymore. 361 * After backend is back to normal the virtualized device may still hold some 362 * state: configuration in use, allocated buffers, client application state etc. 363 * So, in most cases, this will require frontend to implement complex recovery 364 * reconnect logic. Instead, by going into XenbusStateReconfiguring state, 365 * frontend will make sure no new clients of the virtualized device are 366 * accepted, allow existing client(s) to exit gracefully by signaling error 367 * state etc. 368 * Once all the clients are gone frontend can reinitialize the virtualized 369 * device and get into XenbusStateInitialising state again signaling the 370 * backend that a new connection can be made. 371 * 372 * There are multiple conditions possible under which frontend will go from 373 * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS 374 * specific. For example: 375 * 1. The underlying OS framework may provide callbacks to signal that the last 376 * client of the virtualized device has gone and the device can be removed 377 * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue) 378 * to periodically check if this is the right time to re-try removal of 379 * the virtualized device. 380 * 3. By any other means. 381 * 382 ****************************************************************************** 383 * PCM FORMATS 384 ****************************************************************************** 385 * 386 * XENSND_PCM_FORMAT_<format>[_<endian>] 387 * 388 * format: <S/U/F><bits> or <name> 389 * S - signed, U - unsigned, F - float 390 * bits - 8, 16, 24, 32 391 * name - MU_LAW, GSM, etc. 392 * 393 * endian: <LE/BE>, may be absent 394 * LE - Little endian, BE - Big endian 395 */ 396 #define XENSND_PCM_FORMAT_S8 0 397 #define XENSND_PCM_FORMAT_U8 1 398 #define XENSND_PCM_FORMAT_S16_LE 2 399 #define XENSND_PCM_FORMAT_S16_BE 3 400 #define XENSND_PCM_FORMAT_U16_LE 4 401 #define XENSND_PCM_FORMAT_U16_BE 5 402 #define XENSND_PCM_FORMAT_S24_LE 6 403 #define XENSND_PCM_FORMAT_S24_BE 7 404 #define XENSND_PCM_FORMAT_U24_LE 8 405 #define XENSND_PCM_FORMAT_U24_BE 9 406 #define XENSND_PCM_FORMAT_S32_LE 10 407 #define XENSND_PCM_FORMAT_S32_BE 11 408 #define XENSND_PCM_FORMAT_U32_LE 12 409 #define XENSND_PCM_FORMAT_U32_BE 13 410 #define XENSND_PCM_FORMAT_F32_LE 14 /* 4-byte float, IEEE-754 32-bit, */ 411 #define XENSND_PCM_FORMAT_F32_BE 15 /* range -1.0 to 1.0 */ 412 #define XENSND_PCM_FORMAT_F64_LE 16 /* 8-byte float, IEEE-754 64-bit, */ 413 #define XENSND_PCM_FORMAT_F64_BE 17 /* range -1.0 to 1.0 */ 414 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE 18 415 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE 19 416 #define XENSND_PCM_FORMAT_MU_LAW 20 417 #define XENSND_PCM_FORMAT_A_LAW 21 418 #define XENSND_PCM_FORMAT_IMA_ADPCM 22 419 #define XENSND_PCM_FORMAT_MPEG 23 420 #define XENSND_PCM_FORMAT_GSM 24 421 422 /* 423 ****************************************************************************** 424 * REQUEST CODES 425 ****************************************************************************** 426 */ 427 #define XENSND_OP_OPEN 0 428 #define XENSND_OP_CLOSE 1 429 #define XENSND_OP_READ 2 430 #define XENSND_OP_WRITE 3 431 #define XENSND_OP_SET_VOLUME 4 432 #define XENSND_OP_GET_VOLUME 5 433 #define XENSND_OP_MUTE 6 434 #define XENSND_OP_UNMUTE 7 435 436 /* 437 ****************************************************************************** 438 * XENSTORE FIELD AND PATH NAME STRINGS, HELPERS 439 ****************************************************************************** 440 */ 441 #define XENSND_DRIVER_NAME "vsnd" 442 443 #define XENSND_LIST_SEPARATOR "," 444 /* Field names */ 445 #define XENSND_FIELD_BE_VERSIONS "versions" 446 #define XENSND_FIELD_FE_VERSION "version" 447 #define XENSND_FIELD_VCARD_SHORT_NAME "short-name" 448 #define XENSND_FIELD_VCARD_LONG_NAME "long-name" 449 #define XENSND_FIELD_RING_REF "ring-ref" 450 #define XENSND_FIELD_EVT_CHNL "event-channel" 451 #define XENSND_FIELD_DEVICE_NAME "name" 452 #define XENSND_FIELD_TYPE "type" 453 #define XENSND_FIELD_STREAM_UNIQUE_ID "unique-id" 454 #define XENSND_FIELD_CHANNELS_MIN "channels-min" 455 #define XENSND_FIELD_CHANNELS_MAX "channels-max" 456 #define XENSND_FIELD_SAMPLE_RATES "sample-rates" 457 #define XENSND_FIELD_SAMPLE_FORMATS "sample-formats" 458 #define XENSND_FIELD_BUFFER_SIZE "buffer-size" 459 460 /* Stream type field values. */ 461 #define XENSND_STREAM_TYPE_PLAYBACK "p" 462 #define XENSND_STREAM_TYPE_CAPTURE "c" 463 /* Sample rate max string length */ 464 #define XENSND_SAMPLE_RATE_MAX_LEN 11 465 /* Sample format field values */ 466 #define XENSND_SAMPLE_FORMAT_MAX_LEN 24 467 468 #define XENSND_PCM_FORMAT_S8_STR "s8" 469 #define XENSND_PCM_FORMAT_U8_STR "u8" 470 #define XENSND_PCM_FORMAT_S16_LE_STR "s16_le" 471 #define XENSND_PCM_FORMAT_S16_BE_STR "s16_be" 472 #define XENSND_PCM_FORMAT_U16_LE_STR "u16_le" 473 #define XENSND_PCM_FORMAT_U16_BE_STR "u16_be" 474 #define XENSND_PCM_FORMAT_S24_LE_STR "s24_le" 475 #define XENSND_PCM_FORMAT_S24_BE_STR "s24_be" 476 #define XENSND_PCM_FORMAT_U24_LE_STR "u24_le" 477 #define XENSND_PCM_FORMAT_U24_BE_STR "u24_be" 478 #define XENSND_PCM_FORMAT_S32_LE_STR "s32_le" 479 #define XENSND_PCM_FORMAT_S32_BE_STR "s32_be" 480 #define XENSND_PCM_FORMAT_U32_LE_STR "u32_le" 481 #define XENSND_PCM_FORMAT_U32_BE_STR "u32_be" 482 #define XENSND_PCM_FORMAT_F32_LE_STR "float_le" 483 #define XENSND_PCM_FORMAT_F32_BE_STR "float_be" 484 #define XENSND_PCM_FORMAT_F64_LE_STR "float64_le" 485 #define XENSND_PCM_FORMAT_F64_BE_STR "float64_be" 486 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE_STR "iec958_subframe_le" 487 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE_STR "iec958_subframe_be" 488 #define XENSND_PCM_FORMAT_MU_LAW_STR "mu_law" 489 #define XENSND_PCM_FORMAT_A_LAW_STR "a_law" 490 #define XENSND_PCM_FORMAT_IMA_ADPCM_STR "ima_adpcm" 491 #define XENSND_PCM_FORMAT_MPEG_STR "mpeg" 492 #define XENSND_PCM_FORMAT_GSM_STR "gsm" 493 494 495 /* 496 ****************************************************************************** 497 * STATUS RETURN CODES 498 ****************************************************************************** 499 * 500 * Status return code is zero on success and -XEN_EXX on failure. 501 * 502 ****************************************************************************** 503 * Assumptions 504 ****************************************************************************** 505 * o usage of grant reference 0 as invalid grant reference: 506 * grant reference 0 is valid, but never exposed to a PV driver, 507 * because of the fact it is already in use/reserved by the PV console. 508 * o all references in this document to page sizes must be treated 509 * as pages of size XEN_PAGE_SIZE unless otherwise noted. 510 * 511 ****************************************************************************** 512 * Description of the protocol between frontend and backend driver 513 ****************************************************************************** 514 * 515 * The two halves of a Para-virtual sound driver communicate with 516 * each other using shared pages and event channels. 517 * Shared page contains a ring with request/response packets. 518 * 519 * Packets, used for input/output operations, e.g. read/write, set/get volume, 520 * etc., provide offset/length fields in order to allow asynchronous protocol 521 * operation with buffer space sharing: part of the buffer allocated at 522 * XENSND_OP_OPEN can be used for audio samples and part, for example, 523 * for volume control. 524 * 525 * All reserved fields in the structures below must be 0. 526 * 527 *---------------------------------- Requests --------------------------------- 528 * 529 * All request packets have the same length (32 octets) 530 * All request packets have common header: 531 * 0 1 2 3 octet 532 * +----------------+----------------+----------------+----------------+ 533 * | id | operation | reserved | 4 534 * +----------------+----------------+----------------+----------------+ 535 * | reserved | 8 536 * +----------------+----------------+----------------+----------------+ 537 * id - uint16_t, private guest value, echoed in response 538 * operation - uint8_t, operation code, XENSND_OP_??? 539 * 540 * For all packets which use offset and length: 541 * offset - uint32_t, read or write data offset within the shared buffer, 542 * passed with XENSND_OP_OPEN request, octets, 543 * [0; XENSND_OP_OPEN.buffer_sz - 1]. 544 * length - uint32_t, read or write data length, octets 545 * 546 * Request open - open a PCM stream for playback or capture: 547 * 548 * 0 1 2 3 octet 549 * +----------------+----------------+----------------+----------------+ 550 * | id | XENSND_OP_OPEN | reserved | 4 551 * +----------------+----------------+----------------+----------------+ 552 * | reserved | 8 553 * +----------------+----------------+----------------+----------------+ 554 * | pcm_rate | 12 555 * +----------------+----------------+----------------+----------------+ 556 * | pcm_format | pcm_channels | reserved | 16 557 * +----------------+----------------+----------------+----------------+ 558 * | buffer_sz | 20 559 * +----------------+----------------+----------------+----------------+ 560 * | gref_directory | 24 561 * +----------------+----------------+----------------+----------------+ 562 * | reserved | 28 563 * +----------------+----------------+----------------+----------------+ 564 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 565 * +----------------+----------------+----------------+----------------+ 566 * | reserved | 32 567 * +----------------+----------------+----------------+----------------+ 568 * 569 * pcm_rate - uint32_t, stream data rate, Hz 570 * pcm_format - uint8_t, XENSND_PCM_FORMAT_XXX value 571 * pcm_channels - uint8_t, number of channels of this stream, 572 * [channels-min; channels-max] 573 * buffer_sz - uint32_t, buffer size to be allocated, octets 574 * gref_directory - grant_ref_t, a reference to the first shared page 575 * describing shared buffer references. At least one page exists. If shared 576 * buffer size (buffer_sz) exceeds what can be addressed by this single page, 577 * then reference to the next page must be supplied (see gref_dir_next_page 578 * below) 579 */ 580 581 struct xensnd_open_req { 582 uint32_t pcm_rate; 583 uint8_t pcm_format; 584 uint8_t pcm_channels; 585 uint16_t reserved; 586 uint32_t buffer_sz; 587 grant_ref_t gref_directory; 588 }; 589 590 /* 591 * Shared page for XENSND_OP_OPEN buffer descriptor (gref_directory in the 592 * request) employs a list of pages, describing all pages of the shared data 593 * buffer: 594 * 0 1 2 3 octet 595 * +----------------+----------------+----------------+----------------+ 596 * | gref_dir_next_page | 4 597 * +----------------+----------------+----------------+----------------+ 598 * | gref[0] | 8 599 * +----------------+----------------+----------------+----------------+ 600 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 601 * +----------------+----------------+----------------+----------------+ 602 * | gref[i] | i*4+8 603 * +----------------+----------------+----------------+----------------+ 604 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 605 * +----------------+----------------+----------------+----------------+ 606 * | gref[N - 1] | N*4+8 607 * +----------------+----------------+----------------+----------------+ 608 * 609 * gref_dir_next_page - grant_ref_t, reference to the next page describing 610 * page directory. Must be 0 if there are no more pages in the list. 611 * gref[i] - grant_ref_t, reference to a shared page of the buffer 612 * allocated at XENSND_OP_OPEN 613 * 614 * Number of grant_ref_t entries in the whole page directory is not 615 * passed, but instead can be calculated as: 616 * num_grefs_total = (XENSND_OP_OPEN.buffer_sz + XEN_PAGE_SIZE - 1) / 617 * XEN_PAGE_SIZE 618 */ 619 620 struct xensnd_page_directory { 621 grant_ref_t gref_dir_next_page; 622 grant_ref_t gref[1]; /* Variable length */ 623 }; 624 625 /* 626 * Request close - close an opened pcm stream: 627 * 0 1 2 3 octet 628 * +----------------+----------------+----------------+----------------+ 629 * | id | XENSND_OP_CLOSE| reserved | 4 630 * +----------------+----------------+----------------+----------------+ 631 * | reserved | 8 632 * +----------------+----------------+----------------+----------------+ 633 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 634 * +----------------+----------------+----------------+----------------+ 635 * | reserved | 32 636 * +----------------+----------------+----------------+----------------+ 637 * 638 * Request read/write - used for read (for capture) or write (for playback): 639 * 0 1 2 3 octet 640 * +----------------+----------------+----------------+----------------+ 641 * | id | operation | reserved | 4 642 * +----------------+----------------+----------------+----------------+ 643 * | reserved | 8 644 * +----------------+----------------+----------------+----------------+ 645 * | offset | 12 646 * +----------------+----------------+----------------+----------------+ 647 * | length | 16 648 * +----------------+----------------+----------------+----------------+ 649 * | reserved | 20 650 * +----------------+----------------+----------------+----------------+ 651 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 652 * +----------------+----------------+----------------+----------------+ 653 * | reserved | 32 654 * +----------------+----------------+----------------+----------------+ 655 * 656 * operation - XENSND_OP_READ for read or XENSND_OP_WRITE for write 657 */ 658 659 struct xensnd_rw_req { 660 uint32_t offset; 661 uint32_t length; 662 }; 663 664 /* 665 * Request set/get volume - set/get channels' volume of the stream given: 666 * 0 1 2 3 octet 667 * +----------------+----------------+----------------+----------------+ 668 * | id | operation | reserved | 4 669 * +----------------+----------------+----------------+----------------+ 670 * | reserved | 8 671 * +----------------+----------------+----------------+----------------+ 672 * | offset | 12 673 * +----------------+----------------+----------------+----------------+ 674 * | length | 16 675 * +----------------+----------------+----------------+----------------+ 676 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 677 * +----------------+----------------+----------------+----------------+ 678 * | reserved | 32 679 * +----------------+----------------+----------------+----------------+ 680 * 681 * operation - XENSND_OP_SET_VOLUME for volume set 682 * or XENSND_OP_GET_VOLUME for volume get 683 * Buffer passed with XENSND_OP_OPEN is used to exchange volume 684 * values: 685 * 686 * 0 1 2 3 octet 687 * +----------------+----------------+----------------+----------------+ 688 * | channel[0] | 4 689 * +----------------+----------------+----------------+----------------+ 690 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 691 * +----------------+----------------+----------------+----------------+ 692 * | channel[i] | i*4 693 * +----------------+----------------+----------------+----------------+ 694 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 695 * +----------------+----------------+----------------+----------------+ 696 * | channel[N - 1] | (N-1)*4 697 * +----------------+----------------+----------------+----------------+ 698 * 699 * N = XENSND_OP_OPEN.pcm_channels 700 * i - uint8_t, index of a channel 701 * channel[i] - sint32_t, volume of i-th channel 702 * Volume is expressed as a signed value in steps of 0.001 dB, 703 * while 0 being 0 dB. 704 * 705 * Request mute/unmute - mute/unmute stream: 706 * 0 1 2 3 octet 707 * +----------------+----------------+----------------+----------------+ 708 * | id | operation | reserved | 4 709 * +----------------+----------------+----------------+----------------+ 710 * | reserved | 8 711 * +----------------+----------------+----------------+----------------+ 712 * | offset | 12 713 * +----------------+----------------+----------------+----------------+ 714 * | length | 16 715 * +----------------+----------------+----------------+----------------+ 716 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 717 * +----------------+----------------+----------------+----------------+ 718 * | reserved | 32 719 * +----------------+----------------+----------------+----------------+ 720 * 721 * operation - XENSND_OP_MUTE for mute or XENSND_OP_UNMUTE for unmute 722 * Buffer passed with XENSND_OP_OPEN is used to exchange mute/unmute 723 * values: 724 * 725 * 0 octet 726 * +----------------+----------------+----------------+----------------+ 727 * | channel[0] | 4 728 * +----------------+----------------+----------------+----------------+ 729 * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 730 * +----------------+----------------+----------------+----------------+ 731 * | channel[i] | i*4 732 * +----------------+----------------+----------------+----------------+ 733 * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 734 * +----------------+----------------+----------------+----------------+ 735 * | channel[N - 1] | (N-1)*4 736 * +----------------+----------------+----------------+----------------+ 737 * 738 * N = XENSND_OP_OPEN.pcm_channels 739 * i - uint8_t, index of a channel 740 * channel[i] - uint8_t, non-zero if i-th channel needs to be muted/unmuted 741 * 742 *------------------------------------ N.B. ----------------------------------- 743 * 744 * The 'struct xensnd_rw_req' is also used for XENSND_OP_SET_VOLUME, 745 * XENSND_OP_GET_VOLUME, XENSND_OP_MUTE, XENSND_OP_UNMUTE. 746 */ 747 748 /* 749 *---------------------------------- Responses -------------------------------- 750 * 751 * All response packets have the same length (32 octets) 752 * 753 * Response for all requests: 754 * 0 1 2 3 octet 755 * +----------------+----------------+----------------+----------------+ 756 * | id | operation | reserved | 4 757 * +----------------+----------------+----------------+----------------+ 758 * | status | 8 759 * +----------------+----------------+----------------+----------------+ 760 * | reserved | 12 761 * +----------------+----------------+----------------+----------------+ 762 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 763 * +----------------+----------------+----------------+----------------+ 764 * | reserved | 32 765 * +----------------+----------------+----------------+----------------+ 766 * 767 * id - uint16_t, copied from the request 768 * operation - uint8_t, XENSND_OP_* - copied from request 769 * status - int32_t, response status, zero on success and -XEN_EXX on failure 770 */ 771 772 struct xensnd_req { 773 uint16_t id; 774 uint8_t operation; 775 uint8_t reserved[5]; 776 union { 777 struct xensnd_open_req open; 778 struct xensnd_rw_req rw; 779 uint8_t reserved[24]; 780 } op; 781 }; 782 783 struct xensnd_resp { 784 uint16_t id; 785 uint8_t operation; 786 uint8_t reserved; 787 int32_t status; 788 uint8_t reserved1[24]; 789 }; 790 791 DEFINE_RING_TYPES(xen_sndif, struct xensnd_req, struct xensnd_resp); 792 793 #endif /* __XEN_PUBLIC_IO_SNDIF_H__ */ 794