Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: MIT */
0002 /******************************************************************************
0003  * sndif.h
0004  *
0005  * Unified sound-device I/O interface for Xen guest OSes.
0006  *
0007  * Copyright (C) 2013-2015 GlobalLogic Inc.
0008  * Copyright (C) 2016-2017 EPAM Systems Inc.
0009  *
0010  * Authors: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
0011  *          Oleksandr Grytsov <oleksandr_grytsov@epam.com>
0012  *          Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
0013  *          Iurii Konovalenko <iurii.konovalenko@globallogic.com>
0014  */
0015 
0016 #ifndef __XEN_PUBLIC_IO_SNDIF_H__
0017 #define __XEN_PUBLIC_IO_SNDIF_H__
0018 
0019 #include "ring.h"
0020 #include "../grant_table.h"
0021 
0022 /*
0023  ******************************************************************************
0024  *                           Protocol version
0025  ******************************************************************************
0026  */
0027 #define XENSND_PROTOCOL_VERSION 2
0028 
0029 /*
0030  ******************************************************************************
0031  *                  Feature and Parameter Negotiation
0032  ******************************************************************************
0033  *
0034  * Front->back notifications: when enqueuing a new request, sending a
0035  * notification can be made conditional on xensnd_req (i.e., the generic
0036  * hold-off mechanism provided by the ring macros). Backends must set
0037  * xensnd_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()).
0038  *
0039  * Back->front notifications: when enqueuing a new response, sending a
0040  * notification can be made conditional on xensnd_resp (i.e., the generic
0041  * hold-off mechanism provided by the ring macros). Frontends must set
0042  * xensnd_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
0043  *
0044  * The two halves of a para-virtual sound card driver utilize nodes within
0045  * XenStore to communicate capabilities and to negotiate operating parameters.
0046  * This section enumerates these nodes which reside in the respective front and
0047  * backend portions of XenStore, following the XenBus convention.
0048  *
0049  * All data in XenStore is stored as strings. Nodes specifying numeric
0050  * values are encoded in decimal. Integer value ranges listed below are
0051  * expressed as fixed sized integer types capable of storing the conversion
0052  * of a properly formated node string, without loss of information.
0053  *
0054  ******************************************************************************
0055  *                        Example configuration
0056  ******************************************************************************
0057  *
0058  * Note: depending on the use-case backend can expose more sound cards and
0059  * PCM devices/streams than the underlying HW physically has by employing
0060  * SW mixers, configuring virtual sound streams, channels etc.
0061  *
0062  * This is an example of backend and frontend configuration:
0063  *
0064  *--------------------------------- Backend -----------------------------------
0065  *
0066  * /local/domain/0/backend/vsnd/1/0/frontend-id = "1"
0067  * /local/domain/0/backend/vsnd/1/0/frontend = "/local/domain/1/device/vsnd/0"
0068  * /local/domain/0/backend/vsnd/1/0/state = "4"
0069  * /local/domain/0/backend/vsnd/1/0/versions = "1,2"
0070  *
0071  *--------------------------------- Frontend ----------------------------------
0072  *
0073  * /local/domain/1/device/vsnd/0/backend-id = "0"
0074  * /local/domain/1/device/vsnd/0/backend = "/local/domain/0/backend/vsnd/1/0"
0075  * /local/domain/1/device/vsnd/0/state = "4"
0076  * /local/domain/1/device/vsnd/0/version = "1"
0077  *
0078  *----------------------------- Card configuration ----------------------------
0079  *
0080  * /local/domain/1/device/vsnd/0/short-name = "Card short name"
0081  * /local/domain/1/device/vsnd/0/long-name = "Card long name"
0082  * /local/domain/1/device/vsnd/0/sample-rates = "8000,32000,44100,48000,96000"
0083  * /local/domain/1/device/vsnd/0/sample-formats = "s8,u8,s16_le,s16_be"
0084  * /local/domain/1/device/vsnd/0/buffer-size = "262144"
0085  *
0086  *------------------------------- PCM device 0 --------------------------------
0087  *
0088  * /local/domain/1/device/vsnd/0/0/name = "General analog"
0089  * /local/domain/1/device/vsnd/0/0/channels-max = "5"
0090  *
0091  *----------------------------- Stream 0, playback ----------------------------
0092  *
0093  * /local/domain/1/device/vsnd/0/0/0/type = "p"
0094  * /local/domain/1/device/vsnd/0/0/0/sample-formats = "s8,u8"
0095  * /local/domain/1/device/vsnd/0/0/0/unique-id = "0"
0096  *
0097  * /local/domain/1/device/vsnd/0/0/0/ring-ref = "386"
0098  * /local/domain/1/device/vsnd/0/0/0/event-channel = "15"
0099  * /local/domain/1/device/vsnd/0/0/0/evt-ring-ref = "1386"
0100  * /local/domain/1/device/vsnd/0/0/0/evt-event-channel = "215"
0101  *
0102  *------------------------------ Stream 1, capture ----------------------------
0103  *
0104  * /local/domain/1/device/vsnd/0/0/1/type = "c"
0105  * /local/domain/1/device/vsnd/0/0/1/channels-max = "2"
0106  * /local/domain/1/device/vsnd/0/0/1/unique-id = "1"
0107  *
0108  * /local/domain/1/device/vsnd/0/0/1/ring-ref = "384"
0109  * /local/domain/1/device/vsnd/0/0/1/event-channel = "13"
0110  * /local/domain/1/device/vsnd/0/0/1/evt-ring-ref = "1384"
0111  * /local/domain/1/device/vsnd/0/0/1/evt-event-channel = "213"
0112  *
0113  *------------------------------- PCM device 1 --------------------------------
0114  *
0115  * /local/domain/1/device/vsnd/0/1/name = "HDMI-0"
0116  * /local/domain/1/device/vsnd/0/1/sample-rates = "8000,32000,44100"
0117  *
0118  *------------------------------ Stream 0, capture ----------------------------
0119  *
0120  * /local/domain/1/device/vsnd/0/1/0/type = "c"
0121  * /local/domain/1/device/vsnd/0/1/0/unique-id = "2"
0122  *
0123  * /local/domain/1/device/vsnd/0/1/0/ring-ref = "387"
0124  * /local/domain/1/device/vsnd/0/1/0/event-channel = "151"
0125  * /local/domain/1/device/vsnd/0/1/0/evt-ring-ref = "1387"
0126  * /local/domain/1/device/vsnd/0/1/0/evt-event-channel = "351"
0127  *
0128  *------------------------------- PCM device 2 --------------------------------
0129  *
0130  * /local/domain/1/device/vsnd/0/2/name = "SPDIF"
0131  *
0132  *----------------------------- Stream 0, playback ----------------------------
0133  *
0134  * /local/domain/1/device/vsnd/0/2/0/type = "p"
0135  * /local/domain/1/device/vsnd/0/2/0/unique-id = "3"
0136  *
0137  * /local/domain/1/device/vsnd/0/2/0/ring-ref = "389"
0138  * /local/domain/1/device/vsnd/0/2/0/event-channel = "152"
0139  * /local/domain/1/device/vsnd/0/2/0/evt-ring-ref = "1389"
0140  * /local/domain/1/device/vsnd/0/2/0/evt-event-channel = "452"
0141  *
0142  ******************************************************************************
0143  *                            Backend XenBus Nodes
0144  ******************************************************************************
0145  *
0146  *----------------------------- Protocol version ------------------------------
0147  *
0148  * versions
0149  *      Values:         <string>
0150  *
0151  *      List of XENSND_LIST_SEPARATOR separated protocol versions supported
0152  *      by the backend. For example "1,2,3".
0153  *
0154  ******************************************************************************
0155  *                            Frontend XenBus Nodes
0156  ******************************************************************************
0157  *
0158  *-------------------------------- Addressing ---------------------------------
0159  *
0160  * dom-id
0161  *      Values:         <uint16_t>
0162  *
0163  *      Domain identifier.
0164  *
0165  * dev-id
0166  *      Values:         <uint16_t>
0167  *
0168  *      Device identifier.
0169  *
0170  * pcm-dev-idx
0171  *      Values:         <uint8_t>
0172  *
0173  *      Zero based contigous index of the PCM device.
0174  *
0175  * stream-idx
0176  *      Values:         <uint8_t>
0177  *
0178  *      Zero based contigous index of the stream of the PCM device.
0179  *
0180  * The following pattern is used for addressing:
0181  *   /local/domain/<dom-id>/device/vsnd/<dev-id>/<pcm-dev-idx>/<stream-idx>/...
0182  *
0183  *----------------------------- Protocol version ------------------------------
0184  *
0185  * version
0186  *      Values:         <string>
0187  *
0188  *      Protocol version, chosen among the ones supported by the backend.
0189  *
0190  *------------------------------- PCM settings --------------------------------
0191  *
0192  * Every virtualized sound frontend has a set of PCM devices and streams, each
0193  * could be individually configured. Part of the PCM configuration can be
0194  * defined at higher level of the hierarchy and be fully or partially re-used
0195  * by the underlying layers. These configuration values are:
0196  *  o number of channels (min/max)
0197  *  o supported sample rates
0198  *  o supported sample formats.
0199  * E.g. one can define these values for the whole card, device or stream.
0200  * Every underlying layer in turn can re-define some or all of them to better
0201  * fit its needs. For example, card may define number of channels to be
0202  * in [1; 8] range, and some particular stream may be limited to [1; 2] only.
0203  * The rule is that the underlying layer must be a subset of the upper layer
0204  * range.
0205  *
0206  * channels-min
0207  *      Values:         <uint8_t>
0208  *
0209  *      The minimum amount of channels that is supported, [1; channels-max].
0210  *      Optional, if not set or omitted a value of 1 is used.
0211  *
0212  * channels-max
0213  *      Values:         <uint8_t>
0214  *
0215  *      The maximum amount of channels that is supported.
0216  *      Must be at least <channels-min>.
0217  *
0218  * sample-rates
0219  *      Values:         <list of uint32_t>
0220  *
0221  *      List of supported sample rates separated by XENSND_LIST_SEPARATOR.
0222  *      Sample rates are expressed as a list of decimal values w/o any
0223  *      ordering requirement.
0224  *
0225  * sample-formats
0226  *      Values:         <list of XENSND_PCM_FORMAT_XXX_STR>
0227  *
0228  *      List of supported sample formats separated by XENSND_LIST_SEPARATOR.
0229  *      Items must not exceed XENSND_SAMPLE_FORMAT_MAX_LEN length.
0230  *
0231  * buffer-size
0232  *      Values:         <uint32_t>
0233  *
0234  *      The maximum size in octets of the buffer to allocate per stream.
0235  *
0236  *----------------------- Virtual sound card settings -------------------------
0237  * short-name
0238  *      Values:         <char[32]>
0239  *
0240  *      Short name of the virtual sound card. Optional.
0241  *
0242  * long-name
0243  *      Values:         <char[80]>
0244  *
0245  *      Long name of the virtual sound card. Optional.
0246  *
0247  *----------------------------- Device settings -------------------------------
0248  * name
0249  *      Values:         <char[80]>
0250  *
0251  *      Name of the sound device within the virtual sound card. Optional.
0252  *
0253  *----------------------------- Stream settings -------------------------------
0254  *
0255  * type
0256  *      Values:         "p", "c"
0257  *
0258  *      Stream type: "p" - playback stream, "c" - capture stream
0259  *
0260  *      If both capture and playback are needed then two streams need to be
0261  *      defined under the same device.
0262  *
0263  * unique-id
0264  *      Values:         <string>
0265  *
0266  *      After stream initialization it is assigned a unique ID, so every
0267  *      stream of the frontend can be identified by the backend by this ID.
0268  *      This can be UUID or such.
0269  *
0270  *-------------------- Stream Request Transport Parameters --------------------
0271  *
0272  * event-channel
0273  *      Values:         <uint32_t>
0274  *
0275  *      The identifier of the Xen event channel used to signal activity
0276  *      in the ring buffer.
0277  *
0278  * ring-ref
0279  *      Values:         <uint32_t>
0280  *
0281  *      The Xen grant reference granting permission for the backend to map
0282  *      a sole page in a single page sized ring buffer.
0283  *
0284  *--------------------- Stream Event Transport Parameters ---------------------
0285  *
0286  * This communication path is used to deliver asynchronous events from backend
0287  * to frontend, set up per stream.
0288  *
0289  * evt-event-channel
0290  *      Values:         <uint32_t>
0291  *
0292  *      The identifier of the Xen event channel used to signal activity
0293  *      in the ring buffer.
0294  *
0295  * evt-ring-ref
0296  *      Values:         <uint32_t>
0297  *
0298  *      The Xen grant reference granting permission for the backend to map
0299  *      a sole page in a single page sized ring buffer.
0300  *
0301  ******************************************************************************
0302  *                               STATE DIAGRAMS
0303  ******************************************************************************
0304  *
0305  * Tool stack creates front and back state nodes with initial state
0306  * XenbusStateInitialising.
0307  * Tool stack creates and sets up frontend sound configuration nodes per domain.
0308  *
0309  * Front                                Back
0310  * =================================    =====================================
0311  * XenbusStateInitialising              XenbusStateInitialising
0312  *                                       o Query backend device identification
0313  *                                         data.
0314  *                                       o Open and validate backend device.
0315  *                                                      |
0316  *                                                      |
0317  *                                                      V
0318  *                                      XenbusStateInitWait
0319  *
0320  * o Query frontend configuration
0321  * o Allocate and initialize
0322  *   event channels per configured
0323  *   playback/capture stream.
0324  * o Publish transport parameters
0325  *   that will be in effect during
0326  *   this connection.
0327  *              |
0328  *              |
0329  *              V
0330  * XenbusStateInitialised
0331  *
0332  *                                       o Query frontend transport parameters.
0333  *                                       o Connect to the event channels.
0334  *                                                      |
0335  *                                                      |
0336  *                                                      V
0337  *                                      XenbusStateConnected
0338  *
0339  *  o Create and initialize OS
0340  *    virtual sound device instances
0341  *    as per configuration.
0342  *              |
0343  *              |
0344  *              V
0345  * XenbusStateConnected
0346  *
0347  *                                      XenbusStateUnknown
0348  *                                      XenbusStateClosed
0349  *                                      XenbusStateClosing
0350  * o Remove virtual sound device
0351  * o Remove event channels
0352  *              |
0353  *              |
0354  *              V
0355  * XenbusStateClosed
0356  *
0357  *------------------------------- Recovery flow -------------------------------
0358  *
0359  * In case of frontend unrecoverable errors backend handles that as
0360  * if frontend goes into the XenbusStateClosed state.
0361  *
0362  * In case of backend unrecoverable errors frontend tries removing
0363  * the virtualized device. If this is possible at the moment of error,
0364  * then frontend goes into the XenbusStateInitialising state and is ready for
0365  * new connection with backend. If the virtualized device is still in use and
0366  * cannot be removed, then frontend goes into the XenbusStateReconfiguring state
0367  * until either the virtualized device removed or backend initiates a new
0368  * connection. On the virtualized device removal frontend goes into the
0369  * XenbusStateInitialising state.
0370  *
0371  * Note on XenbusStateReconfiguring state of the frontend: if backend has
0372  * unrecoverable errors then frontend cannot send requests to the backend
0373  * and thus cannot provide functionality of the virtualized device anymore.
0374  * After backend is back to normal the virtualized device may still hold some
0375  * state: configuration in use, allocated buffers, client application state etc.
0376  * So, in most cases, this will require frontend to implement complex recovery
0377  * reconnect logic. Instead, by going into XenbusStateReconfiguring state,
0378  * frontend will make sure no new clients of the virtualized device are
0379  * accepted, allow existing client(s) to exit gracefully by signaling error
0380  * state etc.
0381  * Once all the clients are gone frontend can reinitialize the virtualized
0382  * device and get into XenbusStateInitialising state again signaling the
0383  * backend that a new connection can be made.
0384  *
0385  * There are multiple conditions possible under which frontend will go from
0386  * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS
0387  * specific. For example:
0388  * 1. The underlying OS framework may provide callbacks to signal that the last
0389  *    client of the virtualized device has gone and the device can be removed
0390  * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue)
0391  *    to periodically check if this is the right time to re-try removal of
0392  *    the virtualized device.
0393  * 3. By any other means.
0394  *
0395  ******************************************************************************
0396  *                             PCM FORMATS
0397  ******************************************************************************
0398  *
0399  * XENSND_PCM_FORMAT_<format>[_<endian>]
0400  *
0401  * format: <S/U/F><bits> or <name>
0402  *     S - signed, U - unsigned, F - float
0403  *     bits - 8, 16, 24, 32
0404  *     name - MU_LAW, GSM, etc.
0405  *
0406  * endian: <LE/BE>, may be absent
0407  *     LE - Little endian, BE - Big endian
0408  */
0409 #define XENSND_PCM_FORMAT_S8        0
0410 #define XENSND_PCM_FORMAT_U8        1
0411 #define XENSND_PCM_FORMAT_S16_LE    2
0412 #define XENSND_PCM_FORMAT_S16_BE    3
0413 #define XENSND_PCM_FORMAT_U16_LE    4
0414 #define XENSND_PCM_FORMAT_U16_BE    5
0415 #define XENSND_PCM_FORMAT_S24_LE    6
0416 #define XENSND_PCM_FORMAT_S24_BE    7
0417 #define XENSND_PCM_FORMAT_U24_LE    8
0418 #define XENSND_PCM_FORMAT_U24_BE    9
0419 #define XENSND_PCM_FORMAT_S32_LE    10
0420 #define XENSND_PCM_FORMAT_S32_BE    11
0421 #define XENSND_PCM_FORMAT_U32_LE    12
0422 #define XENSND_PCM_FORMAT_U32_BE    13
0423 #define XENSND_PCM_FORMAT_F32_LE    14 /* 4-byte float, IEEE-754 32-bit, */
0424 #define XENSND_PCM_FORMAT_F32_BE    15 /* range -1.0 to 1.0              */
0425 #define XENSND_PCM_FORMAT_F64_LE    16 /* 8-byte float, IEEE-754 64-bit, */
0426 #define XENSND_PCM_FORMAT_F64_BE    17 /* range -1.0 to 1.0              */
0427 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE 18
0428 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE 19
0429 #define XENSND_PCM_FORMAT_MU_LAW    20
0430 #define XENSND_PCM_FORMAT_A_LAW     21
0431 #define XENSND_PCM_FORMAT_IMA_ADPCM 22
0432 #define XENSND_PCM_FORMAT_MPEG      23
0433 #define XENSND_PCM_FORMAT_GSM       24
0434 
0435 /*
0436  ******************************************************************************
0437  *                             REQUEST CODES
0438  ******************************************************************************
0439  */
0440 #define XENSND_OP_OPEN          0
0441 #define XENSND_OP_CLOSE         1
0442 #define XENSND_OP_READ          2
0443 #define XENSND_OP_WRITE         3
0444 #define XENSND_OP_SET_VOLUME        4
0445 #define XENSND_OP_GET_VOLUME        5
0446 #define XENSND_OP_MUTE          6
0447 #define XENSND_OP_UNMUTE        7
0448 #define XENSND_OP_TRIGGER       8
0449 #define XENSND_OP_HW_PARAM_QUERY    9
0450 
0451 #define XENSND_OP_TRIGGER_START     0
0452 #define XENSND_OP_TRIGGER_PAUSE     1
0453 #define XENSND_OP_TRIGGER_STOP      2
0454 #define XENSND_OP_TRIGGER_RESUME    3
0455 
0456 /*
0457  ******************************************************************************
0458  *                                 EVENT CODES
0459  ******************************************************************************
0460  */
0461 #define XENSND_EVT_CUR_POS      0
0462 
0463 /*
0464  ******************************************************************************
0465  *               XENSTORE FIELD AND PATH NAME STRINGS, HELPERS
0466  ******************************************************************************
0467  */
0468 #define XENSND_DRIVER_NAME      "vsnd"
0469 
0470 #define XENSND_LIST_SEPARATOR       ","
0471 /* Field names */
0472 #define XENSND_FIELD_BE_VERSIONS    "versions"
0473 #define XENSND_FIELD_FE_VERSION     "version"
0474 #define XENSND_FIELD_VCARD_SHORT_NAME   "short-name"
0475 #define XENSND_FIELD_VCARD_LONG_NAME    "long-name"
0476 #define XENSND_FIELD_RING_REF       "ring-ref"
0477 #define XENSND_FIELD_EVT_CHNL       "event-channel"
0478 #define XENSND_FIELD_EVT_RING_REF   "evt-ring-ref"
0479 #define XENSND_FIELD_EVT_EVT_CHNL   "evt-event-channel"
0480 #define XENSND_FIELD_DEVICE_NAME    "name"
0481 #define XENSND_FIELD_TYPE       "type"
0482 #define XENSND_FIELD_STREAM_UNIQUE_ID   "unique-id"
0483 #define XENSND_FIELD_CHANNELS_MIN   "channels-min"
0484 #define XENSND_FIELD_CHANNELS_MAX   "channels-max"
0485 #define XENSND_FIELD_SAMPLE_RATES   "sample-rates"
0486 #define XENSND_FIELD_SAMPLE_FORMATS "sample-formats"
0487 #define XENSND_FIELD_BUFFER_SIZE    "buffer-size"
0488 
0489 /* Stream type field values. */
0490 #define XENSND_STREAM_TYPE_PLAYBACK "p"
0491 #define XENSND_STREAM_TYPE_CAPTURE  "c"
0492 /* Sample rate max string length */
0493 #define XENSND_SAMPLE_RATE_MAX_LEN  11
0494 /* Sample format field values */
0495 #define XENSND_SAMPLE_FORMAT_MAX_LEN    24
0496 
0497 #define XENSND_PCM_FORMAT_S8_STR    "s8"
0498 #define XENSND_PCM_FORMAT_U8_STR    "u8"
0499 #define XENSND_PCM_FORMAT_S16_LE_STR    "s16_le"
0500 #define XENSND_PCM_FORMAT_S16_BE_STR    "s16_be"
0501 #define XENSND_PCM_FORMAT_U16_LE_STR    "u16_le"
0502 #define XENSND_PCM_FORMAT_U16_BE_STR    "u16_be"
0503 #define XENSND_PCM_FORMAT_S24_LE_STR    "s24_le"
0504 #define XENSND_PCM_FORMAT_S24_BE_STR    "s24_be"
0505 #define XENSND_PCM_FORMAT_U24_LE_STR    "u24_le"
0506 #define XENSND_PCM_FORMAT_U24_BE_STR    "u24_be"
0507 #define XENSND_PCM_FORMAT_S32_LE_STR    "s32_le"
0508 #define XENSND_PCM_FORMAT_S32_BE_STR    "s32_be"
0509 #define XENSND_PCM_FORMAT_U32_LE_STR    "u32_le"
0510 #define XENSND_PCM_FORMAT_U32_BE_STR    "u32_be"
0511 #define XENSND_PCM_FORMAT_F32_LE_STR    "float_le"
0512 #define XENSND_PCM_FORMAT_F32_BE_STR    "float_be"
0513 #define XENSND_PCM_FORMAT_F64_LE_STR    "float64_le"
0514 #define XENSND_PCM_FORMAT_F64_BE_STR    "float64_be"
0515 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE_STR "iec958_subframe_le"
0516 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE_STR "iec958_subframe_be"
0517 #define XENSND_PCM_FORMAT_MU_LAW_STR    "mu_law"
0518 #define XENSND_PCM_FORMAT_A_LAW_STR "a_law"
0519 #define XENSND_PCM_FORMAT_IMA_ADPCM_STR "ima_adpcm"
0520 #define XENSND_PCM_FORMAT_MPEG_STR  "mpeg"
0521 #define XENSND_PCM_FORMAT_GSM_STR   "gsm"
0522 
0523 
0524 /*
0525  ******************************************************************************
0526  *                          STATUS RETURN CODES
0527  ******************************************************************************
0528  *
0529  * Status return code is zero on success and -XEN_EXX on failure.
0530  *
0531  ******************************************************************************
0532  *                              Assumptions
0533  ******************************************************************************
0534  * o usage of grant reference 0 as invalid grant reference:
0535  *   grant reference 0 is valid, but never exposed to a PV driver,
0536  *   because of the fact it is already in use/reserved by the PV console.
0537  * o all references in this document to page sizes must be treated
0538  *   as pages of size XEN_PAGE_SIZE unless otherwise noted.
0539  *
0540  ******************************************************************************
0541  *       Description of the protocol between frontend and backend driver
0542  ******************************************************************************
0543  *
0544  * The two halves of a Para-virtual sound driver communicate with
0545  * each other using shared pages and event channels.
0546  * Shared page contains a ring with request/response packets.
0547  *
0548  * Packets, used for input/output operations, e.g. read/write, set/get volume,
0549  * etc., provide offset/length fields in order to allow asynchronous protocol
0550  * operation with buffer space sharing: part of the buffer allocated at
0551  * XENSND_OP_OPEN can be used for audio samples and part, for example,
0552  * for volume control.
0553  *
0554  * All reserved fields in the structures below must be 0.
0555  *
0556  *---------------------------------- Requests ---------------------------------
0557  *
0558  * All request packets have the same length (64 octets)
0559  * All request packets have common header:
0560  *         0                1                 2               3        octet
0561  * +----------------+----------------+----------------+----------------+
0562  * |               id                |    operation   |    reserved    | 4
0563  * +----------------+----------------+----------------+----------------+
0564  * |                             reserved                              | 8
0565  * +----------------+----------------+----------------+----------------+
0566  *   id - uint16_t, private guest value, echoed in response
0567  *   operation - uint8_t, operation code, XENSND_OP_???
0568  *
0569  * For all packets which use offset and length:
0570  *   offset - uint32_t, read or write data offset within the shared buffer,
0571  *     passed with XENSND_OP_OPEN request, octets,
0572  *     [0; XENSND_OP_OPEN.buffer_sz - 1].
0573  *   length - uint32_t, read or write data length, octets
0574  *
0575  * Request open - open a PCM stream for playback or capture:
0576  *
0577  *         0                1                 2               3        octet
0578  * +----------------+----------------+----------------+----------------+
0579  * |               id                | XENSND_OP_OPEN |    reserved    | 4
0580  * +----------------+----------------+----------------+----------------+
0581  * |                             reserved                              | 8
0582  * +----------------+----------------+----------------+----------------+
0583  * |                             pcm_rate                              | 12
0584  * +----------------+----------------+----------------+----------------+
0585  * |  pcm_format    |  pcm_channels  |             reserved            | 16
0586  * +----------------+----------------+----------------+----------------+
0587  * |                             buffer_sz                             | 20
0588  * +----------------+----------------+----------------+----------------+
0589  * |                           gref_directory                          | 24
0590  * +----------------+----------------+----------------+----------------+
0591  * |                             period_sz                             | 28
0592  * +----------------+----------------+----------------+----------------+
0593  * |                             reserved                              | 32
0594  * +----------------+----------------+----------------+----------------+
0595  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0596  * +----------------+----------------+----------------+----------------+
0597  * |                             reserved                              | 64
0598  * +----------------+----------------+----------------+----------------+
0599  *
0600  * pcm_rate - uint32_t, stream data rate, Hz
0601  * pcm_format - uint8_t, XENSND_PCM_FORMAT_XXX value
0602  * pcm_channels - uint8_t, number of channels of this stream,
0603  *   [channels-min; channels-max]
0604  * buffer_sz - uint32_t, buffer size to be allocated, octets
0605  * period_sz - uint32_t, event period size, octets
0606  *   This is the requested value of the period at which frontend would
0607  *   like to receive XENSND_EVT_CUR_POS notifications from the backend when
0608  *   stream position advances during playback/capture.
0609  *   It shows how many octets are expected to be played/captured before
0610  *   sending such an event.
0611  *   If set to 0 no XENSND_EVT_CUR_POS events are sent by the backend.
0612  *
0613  * gref_directory - grant_ref_t, a reference to the first shared page
0614  *   describing shared buffer references. At least one page exists. If shared
0615  *   buffer size  (buffer_sz) exceeds what can be addressed by this single page,
0616  *   then reference to the next page must be supplied (see gref_dir_next_page
0617  *   below)
0618  */
0619 
0620 struct xensnd_open_req {
0621     uint32_t pcm_rate;
0622     uint8_t pcm_format;
0623     uint8_t pcm_channels;
0624     uint16_t reserved;
0625     uint32_t buffer_sz;
0626     grant_ref_t gref_directory;
0627     uint32_t period_sz;
0628 };
0629 
0630 /*
0631  * Shared page for XENSND_OP_OPEN buffer descriptor (gref_directory in the
0632  *   request) employs a list of pages, describing all pages of the shared data
0633  *   buffer:
0634  *         0                1                 2               3        octet
0635  * +----------------+----------------+----------------+----------------+
0636  * |                        gref_dir_next_page                         | 4
0637  * +----------------+----------------+----------------+----------------+
0638  * |                              gref[0]                              | 8
0639  * +----------------+----------------+----------------+----------------+
0640  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0641  * +----------------+----------------+----------------+----------------+
0642  * |                              gref[i]                              | i*4+8
0643  * +----------------+----------------+----------------+----------------+
0644  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0645  * +----------------+----------------+----------------+----------------+
0646  * |                             gref[N - 1]                           | N*4+8
0647  * +----------------+----------------+----------------+----------------+
0648  *
0649  * gref_dir_next_page - grant_ref_t, reference to the next page describing
0650  *   page directory. Must be 0 if there are no more pages in the list.
0651  * gref[i] - grant_ref_t, reference to a shared page of the buffer
0652  *   allocated at XENSND_OP_OPEN
0653  *
0654  * Number of grant_ref_t entries in the whole page directory is not
0655  * passed, but instead can be calculated as:
0656  *   num_grefs_total = (XENSND_OP_OPEN.buffer_sz + XEN_PAGE_SIZE - 1) /
0657  *       XEN_PAGE_SIZE
0658  */
0659 
0660 struct xensnd_page_directory {
0661     grant_ref_t gref_dir_next_page;
0662     grant_ref_t gref[1]; /* Variable length */
0663 };
0664 
0665 /*
0666  *  Request close - close an opened pcm stream:
0667  *         0                1                 2               3        octet
0668  * +----------------+----------------+----------------+----------------+
0669  * |               id                | XENSND_OP_CLOSE|    reserved    | 4
0670  * +----------------+----------------+----------------+----------------+
0671  * |                             reserved                              | 8
0672  * +----------------+----------------+----------------+----------------+
0673  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0674  * +----------------+----------------+----------------+----------------+
0675  * |                             reserved                              | 64
0676  * +----------------+----------------+----------------+----------------+
0677  *
0678  * Request read/write - used for read (for capture) or write (for playback):
0679  *         0                1                 2               3        octet
0680  * +----------------+----------------+----------------+----------------+
0681  * |               id                |   operation    |    reserved    | 4
0682  * +----------------+----------------+----------------+----------------+
0683  * |                             reserved                              | 8
0684  * +----------------+----------------+----------------+----------------+
0685  * |                              offset                               | 12
0686  * +----------------+----------------+----------------+----------------+
0687  * |                              length                               | 16
0688  * +----------------+----------------+----------------+----------------+
0689  * |                             reserved                              | 20
0690  * +----------------+----------------+----------------+----------------+
0691  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0692  * +----------------+----------------+----------------+----------------+
0693  * |                             reserved                              | 64
0694  * +----------------+----------------+----------------+----------------+
0695  *
0696  * operation - XENSND_OP_READ for read or XENSND_OP_WRITE for write
0697  */
0698 
0699 struct xensnd_rw_req {
0700     uint32_t offset;
0701     uint32_t length;
0702 };
0703 
0704 /*
0705  * Request set/get volume - set/get channels' volume of the stream given:
0706  *         0                1                 2               3        octet
0707  * +----------------+----------------+----------------+----------------+
0708  * |               id                |   operation    |    reserved    | 4
0709  * +----------------+----------------+----------------+----------------+
0710  * |                             reserved                              | 8
0711  * +----------------+----------------+----------------+----------------+
0712  * |                              offset                               | 12
0713  * +----------------+----------------+----------------+----------------+
0714  * |                              length                               | 16
0715  * +----------------+----------------+----------------+----------------+
0716  * |                             reserved                              | 20
0717  * +----------------+----------------+----------------+----------------+
0718  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0719  * +----------------+----------------+----------------+----------------+
0720  * |                             reserved                              | 64
0721  * +----------------+----------------+----------------+----------------+
0722  *
0723  * operation - XENSND_OP_SET_VOLUME for volume set
0724  *   or XENSND_OP_GET_VOLUME for volume get
0725  * Buffer passed with XENSND_OP_OPEN is used to exchange volume
0726  * values:
0727  *
0728  *         0                1                 2               3        octet
0729  * +----------------+----------------+----------------+----------------+
0730  * |                             channel[0]                            | 4
0731  * +----------------+----------------+----------------+----------------+
0732  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0733  * +----------------+----------------+----------------+----------------+
0734  * |                             channel[i]                            | i*4
0735  * +----------------+----------------+----------------+----------------+
0736  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0737  * +----------------+----------------+----------------+----------------+
0738  * |                           channel[N - 1]                          | (N-1)*4
0739  * +----------------+----------------+----------------+----------------+
0740  *
0741  * N = XENSND_OP_OPEN.pcm_channels
0742  * i - uint8_t, index of a channel
0743  * channel[i] - sint32_t, volume of i-th channel
0744  * Volume is expressed as a signed value in steps of 0.001 dB,
0745  * while 0 being 0 dB.
0746  *
0747  * Request mute/unmute - mute/unmute stream:
0748  *         0                1                 2               3        octet
0749  * +----------------+----------------+----------------+----------------+
0750  * |               id                |   operation    |    reserved    | 4
0751  * +----------------+----------------+----------------+----------------+
0752  * |                             reserved                              | 8
0753  * +----------------+----------------+----------------+----------------+
0754  * |                              offset                               | 12
0755  * +----------------+----------------+----------------+----------------+
0756  * |                              length                               | 16
0757  * +----------------+----------------+----------------+----------------+
0758  * |                             reserved                              | 20
0759  * +----------------+----------------+----------------+----------------+
0760  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0761  * +----------------+----------------+----------------+----------------+
0762  * |                             reserved                              | 64
0763  * +----------------+----------------+----------------+----------------+
0764  *
0765  * operation - XENSND_OP_MUTE for mute or XENSND_OP_UNMUTE for unmute
0766  * Buffer passed with XENSND_OP_OPEN is used to exchange mute/unmute
0767  * values:
0768  *
0769  *                                   0                                 octet
0770  * +----------------+----------------+----------------+----------------+
0771  * |                             channel[0]                            | 4
0772  * +----------------+----------------+----------------+----------------+
0773  * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0774  * +----------------+----------------+----------------+----------------+
0775  * |                             channel[i]                            | i*4
0776  * +----------------+----------------+----------------+----------------+
0777  * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0778  * +----------------+----------------+----------------+----------------+
0779  * |                           channel[N - 1]                          | (N-1)*4
0780  * +----------------+----------------+----------------+----------------+
0781  *
0782  * N = XENSND_OP_OPEN.pcm_channels
0783  * i - uint8_t, index of a channel
0784  * channel[i] - uint8_t, non-zero if i-th channel needs to be muted/unmuted
0785  *
0786  *------------------------------------ N.B. -----------------------------------
0787  *
0788  * The 'struct xensnd_rw_req' is also used for XENSND_OP_SET_VOLUME,
0789  * XENSND_OP_GET_VOLUME, XENSND_OP_MUTE, XENSND_OP_UNMUTE.
0790  *
0791  * Request stream running state change - trigger PCM stream running state
0792  * to start, stop, pause or resume:
0793  *
0794  *         0                1                 2               3        octet
0795  * +----------------+----------------+----------------+----------------+
0796  * |               id                |   _OP_TRIGGER  |    reserved    | 4
0797  * +----------------+----------------+----------------+----------------+
0798  * |                             reserved                              | 8
0799  * +----------------+----------------+----------------+----------------+
0800  * |      type      |                     reserved                     | 12
0801  * +----------------+----------------+----------------+----------------+
0802  * |                             reserved                              | 16
0803  * +----------------+----------------+----------------+----------------+
0804  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0805  * +----------------+----------------+----------------+----------------+
0806  * |                             reserved                              | 64
0807  * +----------------+----------------+----------------+----------------+
0808  *
0809  * type - uint8_t, XENSND_OP_TRIGGER_XXX value
0810  */
0811 
0812 struct xensnd_trigger_req {
0813     uint8_t type;
0814 };
0815 
0816 /*
0817  * Request stream parameter ranges: request intervals and
0818  *   masks of supported ranges for stream configuration values.
0819  *
0820  *   Sound device configuration for a particular stream is a limited subset
0821  *   of the multidimensional configuration available on XenStore, e.g.
0822  *   once the frame rate has been selected there is a limited supported range
0823  *   for sample rates becomes available (which might be the same set configured
0824  *   on XenStore or less). For example, selecting 96kHz sample rate may limit
0825  *   number of channels available for such configuration from 4 to 2, etc.
0826  *   Thus, each call to XENSND_OP_HW_PARAM_QUERY may reduce configuration
0827  *   space making it possible to iteratively get the final stream configuration,
0828  *   used in XENSND_OP_OPEN request.
0829  *
0830  *   See response format for this request.
0831  *
0832  *         0                1                 2               3        octet
0833  * +----------------+----------------+----------------+----------------+
0834  * |               id                | _HW_PARAM_QUERY|    reserved    | 4
0835  * +----------------+----------------+----------------+----------------+
0836  * |                             reserved                              | 8
0837  * +----------------+----------------+----------------+----------------+
0838  * |                     formats mask low 32-bit                       | 12
0839  * +----------------+----------------+----------------+----------------+
0840  * |                     formats mask high 32-bit                      | 16
0841  * +----------------+----------------+----------------+----------------+
0842  * |                              min rate                             | 20
0843  * +----------------+----------------+----------------+----------------+
0844  * |                              max rate                             | 24
0845  * +----------------+----------------+----------------+----------------+
0846  * |                            min channels                           | 28
0847  * +----------------+----------------+----------------+----------------+
0848  * |                            max channels                           | 32
0849  * +----------------+----------------+----------------+----------------+
0850  * |                         min buffer frames                         | 36
0851  * +----------------+----------------+----------------+----------------+
0852  * |                         max buffer frames                         | 40
0853  * +----------------+----------------+----------------+----------------+
0854  * |                         min period frames                         | 44
0855  * +----------------+----------------+----------------+----------------+
0856  * |                         max period frames                         | 48
0857  * +----------------+----------------+----------------+----------------+
0858  * |                             reserved                              | 52
0859  * +----------------+----------------+----------------+----------------+
0860  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0861  * +----------------+----------------+----------------+----------------+
0862  * |                             reserved                              | 64
0863  * +----------------+----------------+----------------+----------------+
0864  *
0865  * formats - uint64_t, bit mask representing values of the parameter
0866  *     made as bitwise OR of (1 << XENSND_PCM_FORMAT_XXX) values
0867  *
0868  * For interval parameters:
0869  *   min - uint32_t, minimum value of the parameter
0870  *   max - uint32_t, maximum value of the parameter
0871  *
0872  * Frame is defined as a product of the number of channels by the
0873  * number of octets per one sample.
0874  */
0875 
0876 struct xensnd_query_hw_param {
0877     uint64_t formats;
0878     struct {
0879         uint32_t min;
0880         uint32_t max;
0881     } rates;
0882     struct {
0883         uint32_t min;
0884         uint32_t max;
0885     } channels;
0886     struct {
0887         uint32_t min;
0888         uint32_t max;
0889     } buffer;
0890     struct {
0891         uint32_t min;
0892         uint32_t max;
0893     } period;
0894 };
0895 
0896 /*
0897  *---------------------------------- Responses --------------------------------
0898  *
0899  * All response packets have the same length (64 octets)
0900  *
0901  * All response packets have common header:
0902  *         0                1                 2               3        octet
0903  * +----------------+----------------+----------------+----------------+
0904  * |               id                |    operation   |    reserved    | 4
0905  * +----------------+----------------+----------------+----------------+
0906  * |                              status                               | 8
0907  * +----------------+----------------+----------------+----------------+
0908  *
0909  * id - uint16_t, copied from the request
0910  * operation - uint8_t, XENSND_OP_* - copied from request
0911  * status - int32_t, response status, zero on success and -XEN_EXX on failure
0912  *
0913  *
0914  * HW parameter query response - response for XENSND_OP_HW_PARAM_QUERY:
0915  *         0                1                 2               3        octet
0916  * +----------------+----------------+----------------+----------------+
0917  * |               id                |    operation   |    reserved    | 4
0918  * +----------------+----------------+----------------+----------------+
0919  * |                              status                               | 8
0920  * +----------------+----------------+----------------+----------------+
0921  * |                     formats mask low 32-bit                       | 12
0922  * +----------------+----------------+----------------+----------------+
0923  * |                     formats mask high 32-bit                      | 16
0924  * +----------------+----------------+----------------+----------------+
0925  * |                              min rate                             | 20
0926  * +----------------+----------------+----------------+----------------+
0927  * |                              max rate                             | 24
0928  * +----------------+----------------+----------------+----------------+
0929  * |                            min channels                           | 28
0930  * +----------------+----------------+----------------+----------------+
0931  * |                            max channels                           | 32
0932  * +----------------+----------------+----------------+----------------+
0933  * |                         min buffer frames                         | 36
0934  * +----------------+----------------+----------------+----------------+
0935  * |                         max buffer frames                         | 40
0936  * +----------------+----------------+----------------+----------------+
0937  * |                         min period frames                         | 44
0938  * +----------------+----------------+----------------+----------------+
0939  * |                         max period frames                         | 48
0940  * +----------------+----------------+----------------+----------------+
0941  * |                             reserved                              | 52
0942  * +----------------+----------------+----------------+----------------+
0943  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0944  * +----------------+----------------+----------------+----------------+
0945  * |                             reserved                              | 64
0946  * +----------------+----------------+----------------+----------------+
0947  *
0948  * Meaning of the values in this response is the same as for
0949  * XENSND_OP_HW_PARAM_QUERY request.
0950  */
0951 
0952 /*
0953  *----------------------------------- Events ----------------------------------
0954  *
0955  * Events are sent via shared page allocated by the front and propagated by
0956  *   evt-event-channel/evt-ring-ref XenStore entries
0957  * All event packets have the same length (64 octets)
0958  * All event packets have common header:
0959  *         0                1                 2               3        octet
0960  * +----------------+----------------+----------------+----------------+
0961  * |               id                |      type      |   reserved     | 4
0962  * +----------------+----------------+----------------+----------------+
0963  * |                             reserved                              | 8
0964  * +----------------+----------------+----------------+----------------+
0965  *
0966  * id - uint16_t, event id, may be used by front
0967  * type - uint8_t, type of the event
0968  *
0969  *
0970  * Current stream position - event from back to front when stream's
0971  *   playback/capture position has advanced:
0972  *         0                1                 2               3        octet
0973  * +----------------+----------------+----------------+----------------+
0974  * |               id                |   _EVT_CUR_POS |   reserved     | 4
0975  * +----------------+----------------+----------------+----------------+
0976  * |                             reserved                              | 8
0977  * +----------------+----------------+----------------+----------------+
0978  * |                         position low 32-bit                       | 12
0979  * +----------------+----------------+----------------+----------------+
0980  * |                         position high 32-bit                      | 16
0981  * +----------------+----------------+----------------+----------------+
0982  * |                             reserved                              | 20
0983  * +----------------+----------------+----------------+----------------+
0984  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0985  * +----------------+----------------+----------------+----------------+
0986  * |                             reserved                              | 64
0987  * +----------------+----------------+----------------+----------------+
0988  *
0989  * position - current value of stream's playback/capture position, octets
0990  *
0991  */
0992 
0993 struct xensnd_cur_pos_evt {
0994     uint64_t position;
0995 };
0996 
0997 struct xensnd_req {
0998     uint16_t id;
0999     uint8_t operation;
1000     uint8_t reserved[5];
1001     union {
1002         struct xensnd_open_req open;
1003         struct xensnd_rw_req rw;
1004         struct xensnd_trigger_req trigger;
1005         struct xensnd_query_hw_param hw_param;
1006         uint8_t reserved[56];
1007     } op;
1008 };
1009 
1010 struct xensnd_resp {
1011     uint16_t id;
1012     uint8_t operation;
1013     uint8_t reserved;
1014     int32_t status;
1015     union {
1016         struct xensnd_query_hw_param hw_param;
1017         uint8_t reserved1[56];
1018     } resp;
1019 };
1020 
1021 struct xensnd_evt {
1022     uint16_t id;
1023     uint8_t type;
1024     uint8_t reserved[5];
1025     union {
1026         struct xensnd_cur_pos_evt cur_pos;
1027         uint8_t reserved[56];
1028     } op;
1029 };
1030 
1031 DEFINE_RING_TYPES(xen_sndif, struct xensnd_req, struct xensnd_resp);
1032 
1033 /*
1034  ******************************************************************************
1035  *                        Back to front events delivery
1036  ******************************************************************************
1037  * In order to deliver asynchronous events from back to front a shared page is
1038  * allocated by front and its granted reference propagated to back via
1039  * XenStore entries (evt-ring-ref/evt-event-channel).
1040  * This page has a common header used by both front and back to synchronize
1041  * access and control event's ring buffer, while back being a producer of the
1042  * events and front being a consumer. The rest of the page after the header
1043  * is used for event packets.
1044  *
1045  * Upon reception of an event(s) front may confirm its reception
1046  * for either each event, group of events or none.
1047  */
1048 
1049 struct xensnd_event_page {
1050     uint32_t in_cons;
1051     uint32_t in_prod;
1052     uint8_t reserved[56];
1053 };
1054 
1055 #define XENSND_EVENT_PAGE_SIZE XEN_PAGE_SIZE
1056 #define XENSND_IN_RING_OFFS (sizeof(struct xensnd_event_page))
1057 #define XENSND_IN_RING_SIZE (XENSND_EVENT_PAGE_SIZE - XENSND_IN_RING_OFFS)
1058 #define XENSND_IN_RING_LEN (XENSND_IN_RING_SIZE / sizeof(struct xensnd_evt))
1059 #define XENSND_IN_RING(page) \
1060     ((struct xensnd_evt *)((char *)(page) + XENSND_IN_RING_OFFS))
1061 #define XENSND_IN_RING_REF(page, idx) \
1062     (XENSND_IN_RING((page))[(idx) % XENSND_IN_RING_LEN])
1063 
1064 #endif /* __XEN_PUBLIC_IO_SNDIF_H__ */