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