/******************************************************************************1* sndif.h2*3* Unified sound-device I/O interface for Xen guest OSes.4*5* Permission is hereby granted, free of charge, to any person obtaining a copy6* of this software and associated documentation files (the "Software"), to7* deal in the Software without restriction, including without limitation the8* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or9* sell copies of the Software, and to permit persons to whom the Software is10* furnished to do so, subject to the following conditions:11*12* The above copyright notice and this permission notice shall be included in13* all copies or substantial portions of the Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE18* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING20* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER21* DEALINGS IN THE SOFTWARE.22*23* Copyright (C) 2013-2015 GlobalLogic Inc.24* Copyright (C) 2016-2017 EPAM Systems Inc.25*26* Authors: Oleksandr Andrushchenko <[email protected]>27* Oleksandr Grytsov <[email protected]>28* Oleksandr Dmytryshyn <[email protected]>29* Iurii Konovalenko <[email protected]>30*/3132#ifndef __XEN_PUBLIC_IO_SNDIF_H__33#define __XEN_PUBLIC_IO_SNDIF_H__3435#include "ring.h"36#include "../grant_table.h"3738/*39******************************************************************************40* Protocol version41******************************************************************************42*/43#define XENSND_PROTOCOL_VERSION 24445/*46******************************************************************************47* Feature and Parameter Negotiation48******************************************************************************49*50* Front->back notifications: when enqueuing a new request, sending a51* notification can be made conditional on xensnd_req (i.e., the generic52* hold-off mechanism provided by the ring macros). Backends must set53* xensnd_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()).54*55* Back->front notifications: when enqueuing a new response, sending a56* notification can be made conditional on xensnd_resp (i.e., the generic57* hold-off mechanism provided by the ring macros). Frontends must set58* xensnd_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).59*60* The two halves of a para-virtual sound card driver utilize nodes within61* XenStore to communicate capabilities and to negotiate operating parameters.62* This section enumerates these nodes which reside in the respective front and63* backend portions of XenStore, following the XenBus convention.64*65* All data in XenStore is stored as strings. Nodes specifying numeric66* values are encoded in decimal. Integer value ranges listed below are67* expressed as fixed sized integer types capable of storing the conversion68* of a properly formated node string, without loss of information.69*70******************************************************************************71* Example configuration72******************************************************************************73*74* Note: depending on the use-case backend can expose more sound cards and75* PCM devices/streams than the underlying HW physically has by employing76* SW mixers, configuring virtual sound streams, channels etc.77*78* This is an example of backend and frontend configuration:79*80*--------------------------------- Backend -----------------------------------81*82* /local/domain/0/backend/vsnd/1/0/frontend-id = "1"83* /local/domain/0/backend/vsnd/1/0/frontend = "/local/domain/1/device/vsnd/0"84* /local/domain/0/backend/vsnd/1/0/state = "4"85* /local/domain/0/backend/vsnd/1/0/versions = "1,2"86*87*--------------------------------- Frontend ----------------------------------88*89* /local/domain/1/device/vsnd/0/backend-id = "0"90* /local/domain/1/device/vsnd/0/backend = "/local/domain/0/backend/vsnd/1/0"91* /local/domain/1/device/vsnd/0/state = "4"92* /local/domain/1/device/vsnd/0/version = "1"93*94*----------------------------- Card configuration ----------------------------95*96* /local/domain/1/device/vsnd/0/short-name = "Card short name"97* /local/domain/1/device/vsnd/0/long-name = "Card long name"98* /local/domain/1/device/vsnd/0/sample-rates = "8000,32000,44100,48000,96000"99* /local/domain/1/device/vsnd/0/sample-formats = "s8,u8,s16_le,s16_be"100* /local/domain/1/device/vsnd/0/buffer-size = "262144"101*102*------------------------------- PCM device 0 --------------------------------103*104* /local/domain/1/device/vsnd/0/0/name = "General analog"105* /local/domain/1/device/vsnd/0/0/channels-max = "5"106*107*----------------------------- Stream 0, playback ----------------------------108*109* /local/domain/1/device/vsnd/0/0/0/type = "p"110* /local/domain/1/device/vsnd/0/0/0/sample-formats = "s8,u8"111* /local/domain/1/device/vsnd/0/0/0/unique-id = "0"112*113* /local/domain/1/device/vsnd/0/0/0/ring-ref = "386"114* /local/domain/1/device/vsnd/0/0/0/event-channel = "15"115* /local/domain/1/device/vsnd/0/0/0/evt-ring-ref = "1386"116* /local/domain/1/device/vsnd/0/0/0/evt-event-channel = "215"117*118*------------------------------ Stream 1, capture ----------------------------119*120* /local/domain/1/device/vsnd/0/0/1/type = "c"121* /local/domain/1/device/vsnd/0/0/1/channels-max = "2"122* /local/domain/1/device/vsnd/0/0/1/unique-id = "1"123*124* /local/domain/1/device/vsnd/0/0/1/ring-ref = "384"125* /local/domain/1/device/vsnd/0/0/1/event-channel = "13"126* /local/domain/1/device/vsnd/0/0/1/evt-ring-ref = "1384"127* /local/domain/1/device/vsnd/0/0/1/evt-event-channel = "213"128*129*------------------------------- PCM device 1 --------------------------------130*131* /local/domain/1/device/vsnd/0/1/name = "HDMI-0"132* /local/domain/1/device/vsnd/0/1/sample-rates = "8000,32000,44100"133*134*------------------------------ Stream 0, capture ----------------------------135*136* /local/domain/1/device/vsnd/0/1/0/type = "c"137* /local/domain/1/device/vsnd/0/1/0/unique-id = "2"138*139* /local/domain/1/device/vsnd/0/1/0/ring-ref = "387"140* /local/domain/1/device/vsnd/0/1/0/event-channel = "151"141* /local/domain/1/device/vsnd/0/1/0/evt-ring-ref = "1387"142* /local/domain/1/device/vsnd/0/1/0/evt-event-channel = "351"143*144*------------------------------- PCM device 2 --------------------------------145*146* /local/domain/1/device/vsnd/0/2/name = "SPDIF"147*148*----------------------------- Stream 0, playback ----------------------------149*150* /local/domain/1/device/vsnd/0/2/0/type = "p"151* /local/domain/1/device/vsnd/0/2/0/unique-id = "3"152*153* /local/domain/1/device/vsnd/0/2/0/ring-ref = "389"154* /local/domain/1/device/vsnd/0/2/0/event-channel = "152"155* /local/domain/1/device/vsnd/0/2/0/evt-ring-ref = "1389"156* /local/domain/1/device/vsnd/0/2/0/evt-event-channel = "452"157*158******************************************************************************159* Backend XenBus Nodes160******************************************************************************161*162*----------------------------- Protocol version ------------------------------163*164* versions165* Values: <string>166*167* List of XENSND_LIST_SEPARATOR separated protocol versions supported168* by the backend. For example "1,2,3".169*170******************************************************************************171* Frontend XenBus Nodes172******************************************************************************173*174*-------------------------------- Addressing ---------------------------------175*176* dom-id177* Values: <uint16_t>178*179* Domain identifier.180*181* dev-id182* Values: <uint16_t>183*184* Device identifier.185*186* pcm-dev-idx187* Values: <uint8_t>188*189* Zero based contigous index of the PCM device.190*191* stream-idx192* Values: <uint8_t>193*194* Zero based contigous index of the stream of the PCM device.195*196* The following pattern is used for addressing:197* /local/domain/<dom-id>/device/vsnd/<dev-id>/<pcm-dev-idx>/<stream-idx>/...198*199*----------------------------- Protocol version ------------------------------200*201* version202* Values: <string>203*204* Protocol version, chosen among the ones supported by the backend.205*206*------------------------------- PCM settings --------------------------------207*208* Every virtualized sound frontend has a set of PCM devices and streams, each209* could be individually configured. Part of the PCM configuration can be210* defined at higher level of the hierarchy and be fully or partially re-used211* by the underlying layers. These configuration values are:212* o number of channels (min/max)213* o supported sample rates214* o supported sample formats.215* E.g. one can define these values for the whole card, device or stream.216* Every underlying layer in turn can re-define some or all of them to better217* fit its needs. For example, card may define number of channels to be218* in [1; 8] range, and some particular stream may be limited to [1; 2] only.219* The rule is that the underlying layer must be a subset of the upper layer220* range.221*222* channels-min223* Values: <uint8_t>224*225* The minimum amount of channels that is supported, [1; channels-max].226* Optional, if not set or omitted a value of 1 is used.227*228* channels-max229* Values: <uint8_t>230*231* The maximum amount of channels that is supported.232* Must be at least <channels-min>.233*234* sample-rates235* Values: <list of uint32_t>236*237* List of supported sample rates separated by XENSND_LIST_SEPARATOR.238* Sample rates are expressed as a list of decimal values w/o any239* ordering requirement.240*241* sample-formats242* Values: <list of XENSND_PCM_FORMAT_XXX_STR>243*244* List of supported sample formats separated by XENSND_LIST_SEPARATOR.245* Items must not exceed XENSND_SAMPLE_FORMAT_MAX_LEN length.246*247* buffer-size248* Values: <uint32_t>249*250* The maximum size in octets of the buffer to allocate per stream.251*252*----------------------- Virtual sound card settings -------------------------253* short-name254* Values: <char[32]>255*256* Short name of the virtual sound card. Optional.257*258* long-name259* Values: <char[80]>260*261* Long name of the virtual sound card. Optional.262*263*----------------------------- Device settings -------------------------------264* name265* Values: <char[80]>266*267* Name of the sound device within the virtual sound card. Optional.268*269*----------------------------- Stream settings -------------------------------270*271* type272* Values: "p", "c"273*274* Stream type: "p" - playback stream, "c" - capture stream275*276* If both capture and playback are needed then two streams need to be277* defined under the same device.278*279* unique-id280* Values: <string>281*282* After stream initialization it is assigned a unique ID, so every283* stream of the frontend can be identified by the backend by this ID.284* This can be UUID or such.285*286*-------------------- Stream Request Transport Parameters --------------------287*288* event-channel289* Values: <uint32_t>290*291* The identifier of the Xen event channel used to signal activity292* in the ring buffer.293*294* ring-ref295* Values: <uint32_t>296*297* The Xen grant reference granting permission for the backend to map298* a sole page in a single page sized ring buffer.299*300*--------------------- Stream Event Transport Parameters ---------------------301*302* This communication path is used to deliver asynchronous events from backend303* to frontend, set up per stream.304*305* evt-event-channel306* Values: <uint32_t>307*308* The identifier of the Xen event channel used to signal activity309* in the ring buffer.310*311* evt-ring-ref312* Values: <uint32_t>313*314* The Xen grant reference granting permission for the backend to map315* a sole page in a single page sized ring buffer.316*317******************************************************************************318* STATE DIAGRAMS319******************************************************************************320*321* Tool stack creates front and back state nodes with initial state322* XenbusStateInitialising.323* Tool stack creates and sets up frontend sound configuration nodes per domain.324*325* Front Back326* ================================= =====================================327* XenbusStateInitialising XenbusStateInitialising328* o Query backend device identification329* data.330* o Open and validate backend device.331* |332* |333* V334* XenbusStateInitWait335*336* o Query frontend configuration337* o Allocate and initialize338* event channels per configured339* playback/capture stream.340* o Publish transport parameters341* that will be in effect during342* this connection.343* |344* |345* V346* XenbusStateInitialised347*348* o Query frontend transport parameters.349* o Connect to the event channels.350* |351* |352* V353* XenbusStateConnected354*355* o Create and initialize OS356* virtual sound device instances357* as per configuration.358* |359* |360* V361* XenbusStateConnected362*363* XenbusStateUnknown364* XenbusStateClosed365* XenbusStateClosing366* o Remove virtual sound device367* o Remove event channels368* |369* |370* V371* XenbusStateClosed372*373*------------------------------- Recovery flow -------------------------------374*375* In case of frontend unrecoverable errors backend handles that as376* if frontend goes into the XenbusStateClosed state.377*378* In case of backend unrecoverable errors frontend tries removing379* the virtualized device. If this is possible at the moment of error,380* then frontend goes into the XenbusStateInitialising state and is ready for381* new connection with backend. If the virtualized device is still in use and382* cannot be removed, then frontend goes into the XenbusStateReconfiguring state383* until either the virtualized device removed or backend initiates a new384* connection. On the virtualized device removal frontend goes into the385* XenbusStateInitialising state.386*387* Note on XenbusStateReconfiguring state of the frontend: if backend has388* unrecoverable errors then frontend cannot send requests to the backend389* and thus cannot provide functionality of the virtualized device anymore.390* After backend is back to normal the virtualized device may still hold some391* state: configuration in use, allocated buffers, client application state etc.392* So, in most cases, this will require frontend to implement complex recovery393* reconnect logic. Instead, by going into XenbusStateReconfiguring state,394* frontend will make sure no new clients of the virtualized device are395* accepted, allow existing client(s) to exit gracefully by signaling error396* state etc.397* Once all the clients are gone frontend can reinitialize the virtualized398* device and get into XenbusStateInitialising state again signaling the399* backend that a new connection can be made.400*401* There are multiple conditions possible under which frontend will go from402* XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS403* specific. For example:404* 1. The underlying OS framework may provide callbacks to signal that the last405* client of the virtualized device has gone and the device can be removed406* 2. Frontend can schedule a deferred work (timer/tasklet/workqueue)407* to periodically check if this is the right time to re-try removal of408* the virtualized device.409* 3. By any other means.410*411******************************************************************************412* PCM FORMATS413******************************************************************************414*415* XENSND_PCM_FORMAT_<format>[_<endian>]416*417* format: <S/U/F><bits> or <name>418* S - signed, U - unsigned, F - float419* bits - 8, 16, 24, 32420* name - MU_LAW, GSM, etc.421*422* endian: <LE/BE>, may be absent423* LE - Little endian, BE - Big endian424*/425#define XENSND_PCM_FORMAT_S8 0426#define XENSND_PCM_FORMAT_U8 1427#define XENSND_PCM_FORMAT_S16_LE 2428#define XENSND_PCM_FORMAT_S16_BE 3429#define XENSND_PCM_FORMAT_U16_LE 4430#define XENSND_PCM_FORMAT_U16_BE 5431#define XENSND_PCM_FORMAT_S24_LE 6432#define XENSND_PCM_FORMAT_S24_BE 7433#define XENSND_PCM_FORMAT_U24_LE 8434#define XENSND_PCM_FORMAT_U24_BE 9435#define XENSND_PCM_FORMAT_S32_LE 10436#define XENSND_PCM_FORMAT_S32_BE 11437#define XENSND_PCM_FORMAT_U32_LE 12438#define XENSND_PCM_FORMAT_U32_BE 13439#define XENSND_PCM_FORMAT_F32_LE 14 /* 4-byte float, IEEE-754 32-bit, */440#define XENSND_PCM_FORMAT_F32_BE 15 /* range -1.0 to 1.0 */441#define XENSND_PCM_FORMAT_F64_LE 16 /* 8-byte float, IEEE-754 64-bit, */442#define XENSND_PCM_FORMAT_F64_BE 17 /* range -1.0 to 1.0 */443#define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE 18444#define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE 19445#define XENSND_PCM_FORMAT_MU_LAW 20446#define XENSND_PCM_FORMAT_A_LAW 21447#define XENSND_PCM_FORMAT_IMA_ADPCM 22448#define XENSND_PCM_FORMAT_MPEG 23449#define XENSND_PCM_FORMAT_GSM 24450451/*452******************************************************************************453* REQUEST CODES454******************************************************************************455*/456#define XENSND_OP_OPEN 0457#define XENSND_OP_CLOSE 1458#define XENSND_OP_READ 2459#define XENSND_OP_WRITE 3460#define XENSND_OP_SET_VOLUME 4461#define XENSND_OP_GET_VOLUME 5462#define XENSND_OP_MUTE 6463#define XENSND_OP_UNMUTE 7464#define XENSND_OP_TRIGGER 8465#define XENSND_OP_HW_PARAM_QUERY 9466467#define XENSND_OP_TRIGGER_START 0468#define XENSND_OP_TRIGGER_PAUSE 1469#define XENSND_OP_TRIGGER_STOP 2470#define XENSND_OP_TRIGGER_RESUME 3471472/*473******************************************************************************474* EVENT CODES475******************************************************************************476*/477#define XENSND_EVT_CUR_POS 0478479/*480******************************************************************************481* XENSTORE FIELD AND PATH NAME STRINGS, HELPERS482******************************************************************************483*/484#define XENSND_DRIVER_NAME "vsnd"485486#define XENSND_LIST_SEPARATOR ","487/* Field names */488#define XENSND_FIELD_BE_VERSIONS "versions"489#define XENSND_FIELD_FE_VERSION "version"490#define XENSND_FIELD_VCARD_SHORT_NAME "short-name"491#define XENSND_FIELD_VCARD_LONG_NAME "long-name"492#define XENSND_FIELD_RING_REF "ring-ref"493#define XENSND_FIELD_EVT_CHNL "event-channel"494#define XENSND_FIELD_EVT_RING_REF "evt-ring-ref"495#define XENSND_FIELD_EVT_EVT_CHNL "evt-event-channel"496#define XENSND_FIELD_DEVICE_NAME "name"497#define XENSND_FIELD_TYPE "type"498#define XENSND_FIELD_STREAM_UNIQUE_ID "unique-id"499#define XENSND_FIELD_CHANNELS_MIN "channels-min"500#define XENSND_FIELD_CHANNELS_MAX "channels-max"501#define XENSND_FIELD_SAMPLE_RATES "sample-rates"502#define XENSND_FIELD_SAMPLE_FORMATS "sample-formats"503#define XENSND_FIELD_BUFFER_SIZE "buffer-size"504505/* Stream type field values. */506#define XENSND_STREAM_TYPE_PLAYBACK "p"507#define XENSND_STREAM_TYPE_CAPTURE "c"508/* Sample rate max string length */509#define XENSND_SAMPLE_RATE_MAX_LEN 11510/* Sample format field values */511#define XENSND_SAMPLE_FORMAT_MAX_LEN 24512513#define XENSND_PCM_FORMAT_S8_STR "s8"514#define XENSND_PCM_FORMAT_U8_STR "u8"515#define XENSND_PCM_FORMAT_S16_LE_STR "s16_le"516#define XENSND_PCM_FORMAT_S16_BE_STR "s16_be"517#define XENSND_PCM_FORMAT_U16_LE_STR "u16_le"518#define XENSND_PCM_FORMAT_U16_BE_STR "u16_be"519#define XENSND_PCM_FORMAT_S24_LE_STR "s24_le"520#define XENSND_PCM_FORMAT_S24_BE_STR "s24_be"521#define XENSND_PCM_FORMAT_U24_LE_STR "u24_le"522#define XENSND_PCM_FORMAT_U24_BE_STR "u24_be"523#define XENSND_PCM_FORMAT_S32_LE_STR "s32_le"524#define XENSND_PCM_FORMAT_S32_BE_STR "s32_be"525#define XENSND_PCM_FORMAT_U32_LE_STR "u32_le"526#define XENSND_PCM_FORMAT_U32_BE_STR "u32_be"527#define XENSND_PCM_FORMAT_F32_LE_STR "float_le"528#define XENSND_PCM_FORMAT_F32_BE_STR "float_be"529#define XENSND_PCM_FORMAT_F64_LE_STR "float64_le"530#define XENSND_PCM_FORMAT_F64_BE_STR "float64_be"531#define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE_STR "iec958_subframe_le"532#define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE_STR "iec958_subframe_be"533#define XENSND_PCM_FORMAT_MU_LAW_STR "mu_law"534#define XENSND_PCM_FORMAT_A_LAW_STR "a_law"535#define XENSND_PCM_FORMAT_IMA_ADPCM_STR "ima_adpcm"536#define XENSND_PCM_FORMAT_MPEG_STR "mpeg"537#define XENSND_PCM_FORMAT_GSM_STR "gsm"538539540/*541******************************************************************************542* STATUS RETURN CODES543******************************************************************************544*545* Status return code is zero on success and -XEN_EXX on failure.546*547******************************************************************************548* Assumptions549******************************************************************************550* o usage of grant reference 0 as invalid grant reference:551* grant reference 0 is valid, but never exposed to a PV driver,552* because of the fact it is already in use/reserved by the PV console.553* o all references in this document to page sizes must be treated554* as pages of size XEN_PAGE_SIZE unless otherwise noted.555*556******************************************************************************557* Description of the protocol between frontend and backend driver558******************************************************************************559*560* The two halves of a Para-virtual sound driver communicate with561* each other using shared pages and event channels.562* Shared page contains a ring with request/response packets.563*564* Packets, used for input/output operations, e.g. read/write, set/get volume,565* etc., provide offset/length fields in order to allow asynchronous protocol566* operation with buffer space sharing: part of the buffer allocated at567* XENSND_OP_OPEN can be used for audio samples and part, for example,568* for volume control.569*570* All reserved fields in the structures below must be 0.571*572*---------------------------------- Requests ---------------------------------573*574* All request packets have the same length (64 octets)575* All request packets have common header:576* 0 1 2 3 octet577* +----------------+----------------+----------------+----------------+578* | id | operation | reserved | 4579* +----------------+----------------+----------------+----------------+580* | reserved | 8581* +----------------+----------------+----------------+----------------+582* id - uint16_t, private guest value, echoed in response583* operation - uint8_t, operation code, XENSND_OP_???584*585* For all packets which use offset and length:586* offset - uint32_t, read or write data offset within the shared buffer,587* passed with XENSND_OP_OPEN request, octets,588* [0; XENSND_OP_OPEN.buffer_sz - 1].589* length - uint32_t, read or write data length, octets590*591* Request open - open a PCM stream for playback or capture:592*593* 0 1 2 3 octet594* +----------------+----------------+----------------+----------------+595* | id | XENSND_OP_OPEN | reserved | 4596* +----------------+----------------+----------------+----------------+597* | reserved | 8598* +----------------+----------------+----------------+----------------+599* | pcm_rate | 12600* +----------------+----------------+----------------+----------------+601* | pcm_format | pcm_channels | reserved | 16602* +----------------+----------------+----------------+----------------+603* | buffer_sz | 20604* +----------------+----------------+----------------+----------------+605* | gref_directory | 24606* +----------------+----------------+----------------+----------------+607* | period_sz | 28608* +----------------+----------------+----------------+----------------+609* | reserved | 32610* +----------------+----------------+----------------+----------------+611* |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|612* +----------------+----------------+----------------+----------------+613* | reserved | 64614* +----------------+----------------+----------------+----------------+615*616* pcm_rate - uint32_t, stream data rate, Hz617* pcm_format - uint8_t, XENSND_PCM_FORMAT_XXX value618* pcm_channels - uint8_t, number of channels of this stream,619* [channels-min; channels-max]620* buffer_sz - uint32_t, buffer size to be allocated, octets621* period_sz - uint32_t, event period size, octets622* This is the requested value of the period at which frontend would623* like to receive XENSND_EVT_CUR_POS notifications from the backend when624* stream position advances during playback/capture.625* It shows how many octets are expected to be played/captured before626* sending such an event.627* If set to 0 no XENSND_EVT_CUR_POS events are sent by the backend.628*629* gref_directory - grant_ref_t, a reference to the first shared page630* describing shared buffer references. At least one page exists. If shared631* buffer size (buffer_sz) exceeds what can be addressed by this single page,632* then reference to the next page must be supplied (see gref_dir_next_page633* below)634*/635636struct xensnd_open_req {637uint32_t pcm_rate;638uint8_t pcm_format;639uint8_t pcm_channels;640uint16_t reserved;641uint32_t buffer_sz;642grant_ref_t gref_directory;643uint32_t period_sz;644};645646/*647* Shared page for XENSND_OP_OPEN buffer descriptor (gref_directory in the648* request) employs a list of pages, describing all pages of the shared data649* buffer:650* 0 1 2 3 octet651* +----------------+----------------+----------------+----------------+652* | gref_dir_next_page | 4653* +----------------+----------------+----------------+----------------+654* | gref[0] | 8655* +----------------+----------------+----------------+----------------+656* |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|657* +----------------+----------------+----------------+----------------+658* | gref[i] | i*4+8659* +----------------+----------------+----------------+----------------+660* |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|661* +----------------+----------------+----------------+----------------+662* | gref[N - 1] | N*4+8663* +----------------+----------------+----------------+----------------+664*665* gref_dir_next_page - grant_ref_t, reference to the next page describing666* page directory. Must be 0 if there are no more pages in the list.667* gref[i] - grant_ref_t, reference to a shared page of the buffer668* allocated at XENSND_OP_OPEN669*670* Number of grant_ref_t entries in the whole page directory is not671* passed, but instead can be calculated as:672* num_grefs_total = (XENSND_OP_OPEN.buffer_sz + XEN_PAGE_SIZE - 1) /673* XEN_PAGE_SIZE674*/675676struct xensnd_page_directory {677grant_ref_t gref_dir_next_page;678grant_ref_t gref[1]; /* Variable length */679};680681/*682* Request close - close an opened pcm stream:683* 0 1 2 3 octet684* +----------------+----------------+----------------+----------------+685* | id | XENSND_OP_CLOSE| reserved | 4686* +----------------+----------------+----------------+----------------+687* | reserved | 8688* +----------------+----------------+----------------+----------------+689* |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|690* +----------------+----------------+----------------+----------------+691* | reserved | 64692* +----------------+----------------+----------------+----------------+693*694* Request read/write - used for read (for capture) or write (for playback):695* 0 1 2 3 octet696* +----------------+----------------+----------------+----------------+697* | id | operation | reserved | 4698* +----------------+----------------+----------------+----------------+699* | reserved | 8700* +----------------+----------------+----------------+----------------+701* | offset | 12702* +----------------+----------------+----------------+----------------+703* | length | 16704* +----------------+----------------+----------------+----------------+705* | reserved | 20706* +----------------+----------------+----------------+----------------+707* |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|708* +----------------+----------------+----------------+----------------+709* | reserved | 64710* +----------------+----------------+----------------+----------------+711*712* operation - XENSND_OP_READ for read or XENSND_OP_WRITE for write713*/714715struct xensnd_rw_req {716uint32_t offset;717uint32_t length;718};719720/*721* Request set/get volume - set/get channels' volume of the stream given:722* 0 1 2 3 octet723* +----------------+----------------+----------------+----------------+724* | id | operation | reserved | 4725* +----------------+----------------+----------------+----------------+726* | reserved | 8727* +----------------+----------------+----------------+----------------+728* | offset | 12729* +----------------+----------------+----------------+----------------+730* | length | 16731* +----------------+----------------+----------------+----------------+732* | reserved | 20733* +----------------+----------------+----------------+----------------+734* |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|735* +----------------+----------------+----------------+----------------+736* | reserved | 64737* +----------------+----------------+----------------+----------------+738*739* operation - XENSND_OP_SET_VOLUME for volume set740* or XENSND_OP_GET_VOLUME for volume get741* Buffer passed with XENSND_OP_OPEN is used to exchange volume742* values:743*744* 0 1 2 3 octet745* +----------------+----------------+----------------+----------------+746* | channel[0] | 4747* +----------------+----------------+----------------+----------------+748* |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|749* +----------------+----------------+----------------+----------------+750* | channel[i] | i*4751* +----------------+----------------+----------------+----------------+752* |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|753* +----------------+----------------+----------------+----------------+754* | channel[N - 1] | (N-1)*4755* +----------------+----------------+----------------+----------------+756*757* N = XENSND_OP_OPEN.pcm_channels758* i - uint8_t, index of a channel759* channel[i] - sint32_t, volume of i-th channel760* Volume is expressed as a signed value in steps of 0.001 dB,761* while 0 being 0 dB.762*763* Request mute/unmute - mute/unmute stream:764* 0 1 2 3 octet765* +----------------+----------------+----------------+----------------+766* | id | operation | reserved | 4767* +----------------+----------------+----------------+----------------+768* | reserved | 8769* +----------------+----------------+----------------+----------------+770* | offset | 12771* +----------------+----------------+----------------+----------------+772* | length | 16773* +----------------+----------------+----------------+----------------+774* | reserved | 20775* +----------------+----------------+----------------+----------------+776* |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|777* +----------------+----------------+----------------+----------------+778* | reserved | 64779* +----------------+----------------+----------------+----------------+780*781* operation - XENSND_OP_MUTE for mute or XENSND_OP_UNMUTE for unmute782* Buffer passed with XENSND_OP_OPEN is used to exchange mute/unmute783* values:784*785* 0 octet786* +----------------+----------------+----------------+----------------+787* | channel[0] | 4788* +----------------+----------------+----------------+----------------+789* +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|790* +----------------+----------------+----------------+----------------+791* | channel[i] | i*4792* +----------------+----------------+----------------+----------------+793* +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|794* +----------------+----------------+----------------+----------------+795* | channel[N - 1] | (N-1)*4796* +----------------+----------------+----------------+----------------+797*798* N = XENSND_OP_OPEN.pcm_channels799* i - uint8_t, index of a channel800* channel[i] - uint8_t, non-zero if i-th channel needs to be muted/unmuted801*802*------------------------------------ N.B. -----------------------------------803*804* The 'struct xensnd_rw_req' is also used for XENSND_OP_SET_VOLUME,805* XENSND_OP_GET_VOLUME, XENSND_OP_MUTE, XENSND_OP_UNMUTE.806*807* Request stream running state change - trigger PCM stream running state808* to start, stop, pause or resume:809*810* 0 1 2 3 octet811* +----------------+----------------+----------------+----------------+812* | id | _OP_TRIGGER | reserved | 4813* +----------------+----------------+----------------+----------------+814* | reserved | 8815* +----------------+----------------+----------------+----------------+816* | type | reserved | 12817* +----------------+----------------+----------------+----------------+818* | reserved | 16819* +----------------+----------------+----------------+----------------+820* |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|821* +----------------+----------------+----------------+----------------+822* | reserved | 64823* +----------------+----------------+----------------+----------------+824*825* type - uint8_t, XENSND_OP_TRIGGER_XXX value826*/827828struct xensnd_trigger_req {829uint8_t type;830};831832/*833* Request stream parameter ranges: request intervals and834* masks of supported ranges for stream configuration values.835*836* Sound device configuration for a particular stream is a limited subset837* of the multidimensional configuration available on XenStore, e.g.838* once the frame rate has been selected there is a limited supported range839* for sample rates becomes available (which might be the same set configured840* on XenStore or less). For example, selecting 96kHz sample rate may limit841* number of channels available for such configuration from 4 to 2, etc.842* Thus, each call to XENSND_OP_HW_PARAM_QUERY may reduce configuration843* space making it possible to iteratively get the final stream configuration,844* used in XENSND_OP_OPEN request.845*846* See response format for this request.847*848* 0 1 2 3 octet849* +----------------+----------------+----------------+----------------+850* | id | _HW_PARAM_QUERY| reserved | 4851* +----------------+----------------+----------------+----------------+852* | reserved | 8853* +----------------+----------------+----------------+----------------+854* | formats mask low 32-bit | 12855* +----------------+----------------+----------------+----------------+856* | formats mask high 32-bit | 16857* +----------------+----------------+----------------+----------------+858* | min rate | 20859* +----------------+----------------+----------------+----------------+860* | max rate | 24861* +----------------+----------------+----------------+----------------+862* | min channels | 28863* +----------------+----------------+----------------+----------------+864* | max channels | 32865* +----------------+----------------+----------------+----------------+866* | min buffer frames | 36867* +----------------+----------------+----------------+----------------+868* | max buffer frames | 40869* +----------------+----------------+----------------+----------------+870* | min period frames | 44871* +----------------+----------------+----------------+----------------+872* | max period frames | 48873* +----------------+----------------+----------------+----------------+874* | reserved | 52875* +----------------+----------------+----------------+----------------+876* |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|877* +----------------+----------------+----------------+----------------+878* | reserved | 64879* +----------------+----------------+----------------+----------------+880*881* formats - uint64_t, bit mask representing values of the parameter882* made as bitwise OR of (1 << XENSND_PCM_FORMAT_XXX) values883*884* For interval parameters:885* min - uint32_t, minimum value of the parameter886* max - uint32_t, maximum value of the parameter887*888* Frame is defined as a product of the number of channels by the889* number of octets per one sample.890*/891892struct xensnd_query_hw_param {893uint64_t formats;894struct {895uint32_t min;896uint32_t max;897} rates;898struct {899uint32_t min;900uint32_t max;901} channels;902struct {903uint32_t min;904uint32_t max;905} buffer;906struct {907uint32_t min;908uint32_t max;909} period;910};911912/*913*---------------------------------- Responses --------------------------------914*915* All response packets have the same length (64 octets)916*917* All response packets have common header:918* 0 1 2 3 octet919* +----------------+----------------+----------------+----------------+920* | id | operation | reserved | 4921* +----------------+----------------+----------------+----------------+922* | status | 8923* +----------------+----------------+----------------+----------------+924*925* id - uint16_t, copied from the request926* operation - uint8_t, XENSND_OP_* - copied from request927* status - int32_t, response status, zero on success and -XEN_EXX on failure928*929*930* HW parameter query response - response for XENSND_OP_HW_PARAM_QUERY:931* 0 1 2 3 octet932* +----------------+----------------+----------------+----------------+933* | id | operation | reserved | 4934* +----------------+----------------+----------------+----------------+935* | status | 8936* +----------------+----------------+----------------+----------------+937* | formats mask low 32-bit | 12938* +----------------+----------------+----------------+----------------+939* | formats mask high 32-bit | 16940* +----------------+----------------+----------------+----------------+941* | min rate | 20942* +----------------+----------------+----------------+----------------+943* | max rate | 24944* +----------------+----------------+----------------+----------------+945* | min channels | 28946* +----------------+----------------+----------------+----------------+947* | max channels | 32948* +----------------+----------------+----------------+----------------+949* | min buffer frames | 36950* +----------------+----------------+----------------+----------------+951* | max buffer frames | 40952* +----------------+----------------+----------------+----------------+953* | min period frames | 44954* +----------------+----------------+----------------+----------------+955* | max period frames | 48956* +----------------+----------------+----------------+----------------+957* | reserved | 52958* +----------------+----------------+----------------+----------------+959* |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|960* +----------------+----------------+----------------+----------------+961* | reserved | 64962* +----------------+----------------+----------------+----------------+963*964* Meaning of the values in this response is the same as for965* XENSND_OP_HW_PARAM_QUERY request.966*/967968/*969*----------------------------------- Events ----------------------------------970*971* Events are sent via shared page allocated by the front and propagated by972* evt-event-channel/evt-ring-ref XenStore entries973* All event packets have the same length (64 octets)974* All event packets have common header:975* 0 1 2 3 octet976* +----------------+----------------+----------------+----------------+977* | id | type | reserved | 4978* +----------------+----------------+----------------+----------------+979* | reserved | 8980* +----------------+----------------+----------------+----------------+981*982* id - uint16_t, event id, may be used by front983* type - uint8_t, type of the event984*985*986* Current stream position - event from back to front when stream's987* playback/capture position has advanced:988* 0 1 2 3 octet989* +----------------+----------------+----------------+----------------+990* | id | _EVT_CUR_POS | reserved | 4991* +----------------+----------------+----------------+----------------+992* | reserved | 8993* +----------------+----------------+----------------+----------------+994* | position low 32-bit | 12995* +----------------+----------------+----------------+----------------+996* | position high 32-bit | 16997* +----------------+----------------+----------------+----------------+998* | reserved | 20999* +----------------+----------------+----------------+----------------+1000* |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|1001* +----------------+----------------+----------------+----------------+1002* | reserved | 641003* +----------------+----------------+----------------+----------------+1004*1005* position - current value of stream's playback/capture position, octets1006*1007*/10081009struct xensnd_cur_pos_evt {1010uint64_t position;1011};10121013struct xensnd_req {1014uint16_t id;1015uint8_t operation;1016uint8_t reserved[5];1017union {1018struct xensnd_open_req open;1019struct xensnd_rw_req rw;1020struct xensnd_trigger_req trigger;1021struct xensnd_query_hw_param hw_param;1022uint8_t reserved[56];1023} op;1024};10251026struct xensnd_resp {1027uint16_t id;1028uint8_t operation;1029uint8_t reserved;1030int32_t status;1031union {1032struct xensnd_query_hw_param hw_param;1033uint8_t reserved1[56];1034} resp;1035};10361037struct xensnd_evt {1038uint16_t id;1039uint8_t type;1040uint8_t reserved[5];1041union {1042struct xensnd_cur_pos_evt cur_pos;1043uint8_t reserved[56];1044} op;1045};10461047DEFINE_RING_TYPES(xen_sndif, struct xensnd_req, struct xensnd_resp);10481049/*1050******************************************************************************1051* Back to front events delivery1052******************************************************************************1053* In order to deliver asynchronous events from back to front a shared page is1054* allocated by front and its granted reference propagated to back via1055* XenStore entries (evt-ring-ref/evt-event-channel).1056* This page has a common header used by both front and back to synchronize1057* access and control event's ring buffer, while back being a producer of the1058* events and front being a consumer. The rest of the page after the header1059* is used for event packets.1060*1061* Upon reception of an event(s) front may confirm its reception1062* for either each event, group of events or none.1063*/10641065struct xensnd_event_page {1066uint32_t in_cons;1067uint32_t in_prod;1068uint8_t reserved[56];1069};10701071#define XENSND_EVENT_PAGE_SIZE 40961072#define XENSND_IN_RING_OFFS (sizeof(struct xensnd_event_page))1073#define XENSND_IN_RING_SIZE (XENSND_EVENT_PAGE_SIZE - XENSND_IN_RING_OFFS)1074#define XENSND_IN_RING_LEN (XENSND_IN_RING_SIZE / sizeof(struct xensnd_evt))1075#define XENSND_IN_RING(page) \1076((struct xensnd_evt *)((char *)(page) + XENSND_IN_RING_OFFS))1077#define XENSND_IN_RING_REF(page, idx) \1078(XENSND_IN_RING((page))[(idx) % XENSND_IN_RING_LEN])10791080#endif /* __XEN_PUBLIC_IO_SNDIF_H__ */10811082/*1083* Local variables:1084* mode: C1085* c-file-style: "BSD"1086* c-basic-offset: 41087* tab-width: 41088* indent-tabs-mode: nil1089* End:1090*/109110921093