xref: /freebsd/sys/contrib/xen/io/sndif.h (revision 8881d206f4e68b564c2c5f50fc717086fc3e827a)
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 4096
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 
1083 /*
1084  * Local variables:
1085  * mode: C
1086  * c-file-style: "BSD"
1087  * c-basic-offset: 4
1088  * tab-width: 4
1089  * indent-tabs-mode: nil
1090  * End:
1091  */
1092