diff mbox series

[Xen-devel,v6,1/1] cameraif: add ABI for para-virtual camera

Message ID 20190322073742.14639-2-andr2000@gmail.com (mailing list archive)
State New, archived
Headers show
Series cameraif: add ABI for para-virtual camera | expand

Commit Message

Oleksandr Andrushchenko March 22, 2019, 7:37 a.m. UTC
From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>

This is the ABI for the two halves of a para-virtualized
camera driver which extends Xen's reach multimedia capabilities even
farther enabling it for video conferencing, In-Vehicle Infotainment,
high definition maps etc.

The initial goal is to support most needed functionality with the
final idea to make it possible to extend the protocol if need be:

1. Provide means for base virtual device configuration:
 - pixel formats
 - resolutions
 - frame rates
2. Support basic camera controls:
 - contrast
 - brightness
 - hue
 - saturation
3. Support streaming control

Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
---
 xen/include/public/io/cameraif.h | 1374 ++++++++++++++++++++++++++++++
 1 file changed, 1374 insertions(+)
 create mode 100644 xen/include/public/io/cameraif.h

Comments

Hans Verkuil March 22, 2019, 8:22 a.m. UTC | #1
On 3/22/19 8:37 AM, Oleksandr Andrushchenko wrote:
> From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> 
> This is the ABI for the two halves of a para-virtualized
> camera driver which extends Xen's reach multimedia capabilities even
> farther enabling it for video conferencing, In-Vehicle Infotainment,
> high definition maps etc.
> 
> The initial goal is to support most needed functionality with the
> final idea to make it possible to extend the protocol if need be:
> 
> 1. Provide means for base virtual device configuration:
>  - pixel formats
>  - resolutions
>  - frame rates
> 2. Support basic camera controls:
>  - contrast
>  - brightness
>  - hue
>  - saturation
> 3. Support streaming control
> 
> Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>

Looks good!

Reviewed-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>

Thank you for all your work on this.

Regards,

	Hans

> ---
>  xen/include/public/io/cameraif.h | 1374 ++++++++++++++++++++++++++++++
>  1 file changed, 1374 insertions(+)
>  create mode 100644 xen/include/public/io/cameraif.h
> 
> diff --git a/xen/include/public/io/cameraif.h b/xen/include/public/io/cameraif.h
> new file mode 100644
> index 000000000000..acbcbf3bd411
> --- /dev/null
> +++ b/xen/include/public/io/cameraif.h
> @@ -0,0 +1,1374 @@
> +/******************************************************************************
> + * cameraif.h
> + *
> + * Unified camera device I/O interface for Xen guest OSes.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + * Copyright (C) 2018-2019 EPAM Systems Inc.
> + *
> + * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> + */
> +
> +#ifndef __XEN_PUBLIC_IO_CAMERAIF_H__
> +#define __XEN_PUBLIC_IO_CAMERAIF_H__
> +
> +#include "ring.h"
> +#include "../grant_table.h"
> +
> +/*
> + ******************************************************************************
> + *                           Protocol version
> + ******************************************************************************
> + */
> +#define XENCAMERA_PROTOCOL_VERSION     "1"
> +
> +/*
> + ******************************************************************************
> + *                  Feature and Parameter Negotiation
> + ******************************************************************************
> + *
> + * Front->back notifications: when enqueuing a new request, sending a
> + * notification can be made conditional on xencamera_req (i.e., the generic
> + * hold-off mechanism provided by the ring macros). Backends must set
> + * xencamera_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()).
> + *
> + * Back->front notifications: when enqueuing a new response, sending a
> + * notification can be made conditional on xencamera_resp (i.e., the generic
> + * hold-off mechanism provided by the ring macros). Frontends must set
> + * xencamera_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
> + *
> + * The two halves of a para-virtual camera driver utilize nodes within
> + * XenStore to communicate capabilities and to negotiate operating parameters.
> + * This section enumerates these nodes which reside in the respective front and
> + * backend portions of XenStore, following the XenBus convention.
> + *
> + * All data in XenStore is stored as strings. Nodes specifying numeric
> + * values are encoded in decimal. Integer value ranges listed below are
> + * expressed as fixed sized integer types capable of storing the conversion
> + * of a properly formatted node string, without loss of information.
> + *
> + ******************************************************************************
> + *                        Example configuration
> + ******************************************************************************
> + *
> + * This is an example of backend and frontend configuration:
> + *
> + *--------------------------------- Backend -----------------------------------
> + *
> + * /local/domain/0/backend/vcamera/1/0/frontend-id = "1"
> + * /local/domain/0/backend/vcamera/1/0/frontend = "/local/domain/1/device/vcamera/0"
> + * /local/domain/0/backend/vcamera/1/0/state = "4"
> + * /local/domain/0/backend/vcamera/1/0/versions = "1,2"
> + *
> + *--------------------------------- Frontend ----------------------------------
> + *
> + * /local/domain/1/device/vcamera/0/backend-id = "0"
> + * /local/domain/1/device/vcamera/0/backend = "/local/domain/0/backend/vcamera/1"
> + * /local/domain/1/device/vcamera/0/state = "4"
> + * /local/domain/1/device/vcamera/0/version = "1"
> + * /local/domain/1/device/vcamera/0/be-alloc = "1"
> + *
> + *---------------------------- Device 0 configuration -------------------------
> + *
> + * /local/domain/1/device/vcamera/0/max-buffers = "3"
> + * /local/domain/1/device/vcamera/0/controls = "contrast,hue"
> + * /local/domain/1/device/vcamera/0/formats/YUYV/640x480/frame-rates = "30/1,15/1"
> + * /local/domain/1/device/vcamera/0/formats/YUYV/1920x1080/frame-rates = "15/2"
> + * /local/domain/1/device/vcamera/0/formats/BGRA/640x480/frame-rates = "15/1,15/2"
> + * /local/domain/1/device/vcamera/0/formats/BGRA/1200x720/frame-rates = "15/2"
> + * /local/domain/1/device/vcamera/0/unique-id = "0"
> + * /local/domain/1/device/vcamera/0/req-ring-ref = "2832"
> + * /local/domain/1/device/vcamera/0/req-event-channel = "15"
> + * /local/domain/1/device/vcamera/0/evt-ring-ref = "387"
> + * /local/domain/1/device/vcamera/0/evt-event-channel = "16"
> + *
> + *---------------------------- Device 1 configuration -------------------------
> + *
> + * /local/domain/1/device/vcamera/1/max-buffers = "8"
> + * /local/domain/1/device/vcamera/1/controls = "brightness,saturation,hue"
> + * /local/domain/1/device/vcamera/1/formats/YUYV/640x480/frame-rates = "30/1,15/2"
> + * /local/domain/1/device/vcamera/1/formats/YUYV/1920x1080/frame-rates = "15/2"
> + * /local/domain/1/device/vcamera/1/unique-id = "1"
> + * /local/domain/1/device/vcamera/1/req-ring-ref = "2833"
> + * /local/domain/1/device/vcamera/1/req-event-channel = "17"
> + * /local/domain/1/device/vcamera/1/evt-ring-ref = "388"
> + * /local/domain/1/device/vcamera/1/evt-event-channel = "18"
> + *
> + ******************************************************************************
> + *                            Backend XenBus Nodes
> + ******************************************************************************
> + *
> + *----------------------------- Protocol version ------------------------------
> + *
> + * versions
> + *      Values:         <string>
> + *
> + *      List of XENCAMERA_LIST_SEPARATOR separated protocol versions supported
> + *      by the backend. For example "1,2,3".
> + *
> + ******************************************************************************
> + *                            Frontend XenBus Nodes
> + ******************************************************************************
> + *
> + *-------------------------------- Addressing ---------------------------------
> + *
> + * dom-id
> + *      Values:         <uint16_t>
> + *
> + *      Domain identifier.
> + *
> + * dev-id
> + *      Values:         <uint16_t>
> + *
> + *      Device identifier.
> + *
> + *      /local/domain/<dom-id>/device/vcamera/<dev-id>/...
> + *
> + *----------------------------- Protocol version ------------------------------
> + *
> + * version
> + *      Values:         <string>
> + *
> + *      Protocol version, chosen among the ones supported by the backend.
> + *
> + *------------------------- Backend buffer allocation -------------------------
> + *
> + * be-alloc
> + *      Values:         "0", "1"
> + *
> + *      If value is set to "1", then backend will be the buffer
> + *      provider/allocator for this domain during XENCAMERA_OP_BUF_CREATE
> + *      operation.
> + *      If value is not "1" or omitted frontend must allocate buffers itself.
> + *
> + *------------------------------- Camera settings -----------------------------
> + *
> + * unique-id
> + *      Values:         <string>
> + *
> + *      After device instance initialization each camera is assigned a
> + *      unique ID, so it can be identified by the backend by this ID.
> + *      This can be UUID or such.
> + *
> + * max-buffers
> + *      Values:         <uint8_t>
> + *
> + *      Maximum number of camera buffers this frontend may use.
> + *
> + * controls
> + *      Values:         <list of string>
> + *
> + *      List of supported camera controls separated by XENCAMERA_LIST_SEPARATOR.
> + *      Camera controls are expressed as a list of string values w/o any
> + *      ordering requirement.
> + *
> + * formats
> + *      Values:         <format, char[7]>
> + *
> + *      Formats are organized as a set of directories one per each
> + *      supported pixel format. The name of the directory is the
> + *      corresponding FOURCC string label. The next level of
> + *      the directory under <formats> represents supported resolutions.
> + *      If the format represents a big-endian variant of a little
> + *      endian format, then the "-BE" suffix must be added. E.g. 'AR15' vs
> + *      'AR15-BE'.
> + *      If FOURCC string label has spaces then those are only allowed to
> + *      be at the end of the label and must be trimmed, for example
> + *      'Y16' and 'Y16-BE' will be trimmed.
> + *
> + * resolution
> + *      Values:         <width, uint32_t>x<height, uint32_t>
> + *
> + *      Resolutions are organized as a set of directories one per each
> + *      supported resolution under corresponding <formats> directory.
> + *      The name of the directory is the supported width and height
> + *      of the camera resolution in pixels.
> + *
> + * frame-rates
> + *      Values:         <numerator, uint32_t>/<denominator, uint32_t>
> + *
> + *      List of XENCAMERA_FRAME_RATE_SEPARATOR separated supported frame rates
> + *      of the camera expressed as numerator and denominator of the
> + *      corresponding frame rate.
> + *
> + *------------------- Camera Request Transport Parameters ---------------------
> + *
> + * This communication path is used to deliver requests from frontend to backend
> + * and get the corresponding responses from backend to frontend,
> + * set up per virtual camera device.
> + *
> + * req-event-channel
> + *      Values:         <uint32_t>
> + *
> + *      The identifier of the Xen camera's control event channel
> + *      used to signal activity in the ring buffer.
> + *
> + * req-ring-ref
> + *      Values:         <uint32_t>
> + *
> + *      The Xen grant reference granting permission for the backend to map
> + *      a sole page of camera's control ring buffer.
> + *
> + *-------------------- Camera Event Transport Parameters ----------------------
> + *
> + * This communication path is used to deliver asynchronous events from backend
> + * to frontend, set up per virtual camera device.
> + *
> + * evt-event-channel
> + *      Values:         <uint32_t>
> + *
> + *      The identifier of the Xen camera's event channel
> + *      used to signal activity in the ring buffer.
> + *
> + * evt-ring-ref
> + *      Values:         <uint32_t>
> + *
> + *      The Xen grant reference granting permission for the backend to map
> + *      a sole page of camera's event ring buffer.
> + */
> +
> +/*
> + ******************************************************************************
> + *                               STATE DIAGRAMS
> + ******************************************************************************
> + *
> + * Tool stack creates front and back state nodes with initial state
> + * XenbusStateInitialising.
> + * Tool stack creates and sets up frontend camera configuration
> + * nodes per domain.
> + *
> + *-------------------------------- Normal flow --------------------------------
> + *
> + * Front                                Back
> + * =================================    =====================================
> + * XenbusStateInitialising              XenbusStateInitialising
> + *                                       o Query backend device identification
> + *                                         data.
> + *                                       o Open and validate backend device.
> + *                                                |
> + *                                                |
> + *                                                V
> + *                                      XenbusStateInitWait
> + *
> + * o Query frontend configuration
> + * o Allocate and initialize
> + *   event channels per configured
> + *   camera.
> + * o Publish transport parameters
> + *   that will be in effect during
> + *   this connection.
> + *              |
> + *              |
> + *              V
> + * XenbusStateInitialised
> + *
> + *                                       o Query frontend transport parameters.
> + *                                       o Connect to the event channels.
> + *                                                |
> + *                                                |
> + *                                                V
> + *                                      XenbusStateConnected
> + *
> + *  o Create and initialize OS
> + *    virtual camera as per
> + *    configuration.
> + *              |
> + *              |
> + *              V
> + * XenbusStateConnected
> + *
> + *                                      XenbusStateUnknown
> + *                                      XenbusStateClosed
> + *                                      XenbusStateClosing
> + * o Remove virtual camera device
> + * o Remove event channels
> + *              |
> + *              |
> + *              V
> + * XenbusStateClosed
> + *
> + *------------------------------- Recovery flow -------------------------------
> + *
> + * In case of frontend unrecoverable errors backend handles that as
> + * if frontend goes into the XenbusStateClosed state.
> + *
> + * In case of backend unrecoverable errors frontend tries removing
> + * the virtualized device. If this is possible at the moment of error,
> + * then frontend goes into the XenbusStateInitialising state and is ready for
> + * new connection with backend. If the virtualized device is still in use and
> + * cannot be removed, then frontend goes into the XenbusStateReconfiguring state
> + * until either the virtualized device is removed or backend initiates a new
> + * connection. On the virtualized device removal frontend goes into the
> + * XenbusStateInitialising state.
> + *
> + * Note on XenbusStateReconfiguring state of the frontend: if backend has
> + * unrecoverable errors then frontend cannot send requests to the backend
> + * and thus cannot provide functionality of the virtualized device anymore.
> + * After backend is back to normal the virtualized device may still hold some
> + * state: configuration in use, allocated buffers, client application state etc.
> + * In most cases, this will require frontend to implement complex recovery
> + * reconnect logic. Instead, by going into XenbusStateReconfiguring state,
> + * frontend will make sure no new clients of the virtualized device are
> + * accepted, allow existing client(s) to exit gracefully by signaling error
> + * state etc.
> + * Once all the clients are gone frontend can reinitialize the virtualized
> + * device and get into XenbusStateInitialising state again signaling the
> + * backend that a new connection can be made.
> + *
> + * There are multiple conditions possible under which frontend will go from
> + * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS
> + * specific. For example:
> + * 1. The underlying OS framework may provide callbacks to signal that the last
> + *    client of the virtualized device has gone and the device can be removed
> + * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue)
> + *    to periodically check if this is the right time to re-try removal of
> + *    the virtualized device.
> + * 3. By any other means.
> + *
> + ******************************************************************************
> + *                             REQUEST CODES
> + ******************************************************************************
> + */
> +#define XENCAMERA_OP_CONFIG_SET        0x00
> +#define XENCAMERA_OP_CONFIG_GET        0x01
> +#define XENCAMERA_OP_CONFIG_VALIDATE   0x02
> +#define XENCAMERA_OP_FRAME_RATE_SET    0x03
> +#define XENCAMERA_OP_BUF_GET_LAYOUT    0x04
> +#define XENCAMERA_OP_BUF_REQUEST       0x05
> +#define XENCAMERA_OP_BUF_CREATE        0x06
> +#define XENCAMERA_OP_BUF_DESTROY       0x07
> +#define XENCAMERA_OP_BUF_QUEUE         0x08
> +#define XENCAMERA_OP_BUF_DEQUEUE       0x09
> +#define XENCAMERA_OP_CTRL_ENUM         0x0a
> +#define XENCAMERA_OP_CTRL_SET          0x0b
> +#define XENCAMERA_OP_CTRL_GET          0x0c
> +#define XENCAMERA_OP_STREAM_START      0x0d
> +#define XENCAMERA_OP_STREAM_STOP       0x0e
> +
> +#define XENCAMERA_CTRL_BRIGHTNESS      0
> +#define XENCAMERA_CTRL_CONTRAST        1
> +#define XENCAMERA_CTRL_SATURATION      2
> +#define XENCAMERA_CTRL_HUE             3
> +
> +/* Number of supported controls. */
> +#define XENCAMERA_MAX_CTRL             4
> +
> +/* Control is read-only. */
> +#define XENCAMERA_CTRL_FLG_RO          (1 << 0)
> +/* Control is write-only. */
> +#define XENCAMERA_CTRL_FLG_WO          (1 << 1)
> +/* Control's value is volatile. */
> +#define XENCAMERA_CTRL_FLG_VOLATILE    (1 << 2)
> +
> +/* Supported color spaces. */
> +#define XENCAMERA_COLORSPACE_DEFAULT   0
> +#define XENCAMERA_COLORSPACE_SMPTE170M 1
> +#define XENCAMERA_COLORSPACE_REC709    2
> +#define XENCAMERA_COLORSPACE_SRGB      3
> +#define XENCAMERA_COLORSPACE_OPRGB     4
> +#define XENCAMERA_COLORSPACE_BT2020    5
> +#define XENCAMERA_COLORSPACE_DCI_P3    6
> +
> +/* Color space transfer function. */
> +#define XENCAMERA_XFER_FUNC_DEFAULT    0
> +#define XENCAMERA_XFER_FUNC_709        1
> +#define XENCAMERA_XFER_FUNC_SRGB       2
> +#define XENCAMERA_XFER_FUNC_OPRGB      3
> +#define XENCAMERA_XFER_FUNC_NONE       4
> +#define XENCAMERA_XFER_FUNC_DCI_P3     5
> +#define XENCAMERA_XFER_FUNC_SMPTE2084  6
> +
> +/* Color space Y’CbCr encoding. */
> +#define XENCAMERA_YCBCR_ENC_IGNORE           0
> +#define XENCAMERA_YCBCR_ENC_601              1
> +#define XENCAMERA_YCBCR_ENC_709              2
> +#define XENCAMERA_YCBCR_ENC_XV601            3
> +#define XENCAMERA_YCBCR_ENC_XV709            4
> +#define XENCAMERA_YCBCR_ENC_BT2020           5
> +#define XENCAMERA_YCBCR_ENC_BT2020_CONST_LUM 6
> +
> +/* Quantization range. */
> +#define XENCAMERA_QUANTIZATION_DEFAULT       0
> +#define XENCAMERA_QUANTIZATION_FULL_RANGE    1
> +#define XENCAMERA_QUANTIZATION_LIM_RANGE     2
> +
> +/*
> + ******************************************************************************
> + *                                 EVENT CODES
> + ******************************************************************************
> + */
> +#define XENCAMERA_EVT_FRAME_AVAIL      0x00
> +#define XENCAMERA_EVT_CTRL_CHANGE      0x01
> +
> +/*
> + ******************************************************************************
> + *               XENSTORE FIELD AND PATH NAME STRINGS, HELPERS
> + ******************************************************************************
> + */
> +#define XENCAMERA_DRIVER_NAME          "vcamera"
> +
> +#define XENCAMERA_LIST_SEPARATOR       ","
> +#define XENCAMERA_RESOLUTION_SEPARATOR "x"
> +#define XENCAMERA_FRACTION_SEPARATOR   "/"
> +
> +#define XENCAMERA_FIELD_BE_VERSIONS    "versions"
> +#define XENCAMERA_FIELD_FE_VERSION     "version"
> +#define XENCAMERA_FIELD_REQ_RING_REF   "req-ring-ref"
> +#define XENCAMERA_FIELD_REQ_CHANNEL    "req-event-channel"
> +#define XENCAMERA_FIELD_EVT_RING_REF   "evt-ring-ref"
> +#define XENCAMERA_FIELD_EVT_CHANNEL    "evt-event-channel"
> +#define XENCAMERA_FIELD_MAX_BUFFERS    "max-buffers"
> +#define XENCAMERA_FIELD_CONTROLS       "controls"
> +#define XENCAMERA_FIELD_FORMATS        "formats"
> +#define XENCAMERA_FIELD_FRAME_RATES    "frame-rates"
> +#define XENCAMERA_FIELD_BE_ALLOC       "be-alloc"
> +#define XENCAMERA_FIELD_UNIQUE_ID      "unique-id"
> +
> +#define XENCAMERA_CTRL_BRIGHTNESS_STR  "brightness"
> +#define XENCAMERA_CTRL_CONTRAST_STR    "contrast"
> +#define XENCAMERA_CTRL_SATURATION_STR  "saturation"
> +#define XENCAMERA_CTRL_HUE_STR         "hue"
> +
> +#define XENCAMERA_FOURCC_BIGENDIAN_STR "-BE"
> +
> +/* Maximum number of buffer planes supported. */
> +#define XENCAMERA_MAX_PLANE            4
> +
> +/*
> + ******************************************************************************
> + *                          STATUS RETURN CODES
> + ******************************************************************************
> + *
> + * Status return code is zero on success and -XEN_EXX on failure.
> + *
> + ******************************************************************************
> + *                              Assumptions
> + ******************************************************************************
> + *
> + * - usage of grant reference 0 as invalid grant reference:
> + *   grant reference 0 is valid, but never exposed to a PV driver,
> + *   because of the fact it is already in use/reserved by the PV console.
> + * - all references in this document to page sizes must be treated
> + *   as pages of size XEN_PAGE_SIZE unless otherwise noted.
> + * - all FOURCC mappings used for configuration and messaging are
> + *   Linux V4L2 ones: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/videodev2.h
> + *   with the following exceptions:
> + *     - characters are allowed in [0x20; 0x7f] range
> + *     - when used for XenStore configuration entries the following
> + *       are not allowed:
> + *       - '/', '\', ' ' (space), '<', '>', ':', '"', '|', '?', '*'
> + *       - if trailing spaces are part of the FOURCC code then those must be
> + *         trimmed
> + *
> + *
> + ******************************************************************************
> + *       Description of the protocol between frontend and backend driver
> + ******************************************************************************
> + *
> + * The two halves of a Para-virtual camera driver communicate with
> + * each other using shared pages and event channels.
> + * Shared page contains a ring with request/response packets.
> + *
> + * All reserved fields in the structures below must be 0.
> + *
> + * For all request/response/event packets:
> + *   - frame rate parameter is represented as a pair of 4 octet long
> + *     numerator and denominator:
> + *       - frame_rate_numer - uint32_t, numerator of the frame rate
> + *       - frame_rate_denom - uint32_t, denominator of the frame rate
> + *     The corresponding frame rate (Hz) is calculated as:
> + *       frame_rate = frame_rate_numer / frame_rate_denom
> + *   - buffer index is a zero based index of the buffer. Must be less than
> + *     the value of XENCAMERA_OP_CONFIG_SET.num_bufs response:
> + *       - index - uint8_t, index of the buffer.
> + *
> + *
> + *---------------------------------- Requests ---------------------------------
> + *
> + * All request packets have the same length (64 octets).
> + * All request packets have common header:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                |    operation   |   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + *   id - uint16_t, private guest value, echoed in response.
> + *   operation - uint8_t, operation code, XENCAMERA_OP_XXX.
> + *
> + *
> + * Request to set/validate the configuration - request to set the
> + * configuration/mode of the camera (XENCAMERA_OP_CONFIG_SET) or to
> + * check if the configuration is valid and can be used
> + * (XENCAMERA_OP_CONFIG_VALIDATE):
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                | _OP_CONFIG_XXX |   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |                            pixel format                           | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                               width                               | 16
> + * +----------------+----------------+----------------+----------------+
> + * |                               height                              | 20
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 24
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * pixel_format - uint32_t, pixel format to be used, FOURCC code.
> + * width - uint32_t, width in pixels.
> + * height - uint32_t, height in pixels.
> + *
> + * See response format for this request.
> + *
> + * Notes:
> + *  - the only difference between XENCAMERA_OP_CONFIG_VALIDATE and
> + *    XENCAMERA_OP_CONFIG_SET is that the former doesn't actually change
> + *    camera configuration, but queries if the configuration is valid.
> + *    This can be used while stream is active and/or buffers allocated.
> + *  - frontend must check the corresponding response in order to see
> + *    if the values reported back by the backend do match the desired ones
> + *    and can be accepted.
> + *  - frontend may send multiple XENCAMERA_OP_CONFIG_SET requests before
> + *    sending XENCAMERA_OP_STREAM_START request to update or tune the
> + *    final stream configuration.
> + *  - configuration cannot be changed during active streaming, e.g.
> + *    after XENCAMERA_OP_STREAM_START and before XENCAMERA_OP_STREAM_STOP
> + *    requests.
> + */
> +struct xencamera_config_req {
> +    uint32_t pixel_format;
> +    uint32_t width;
> +    uint32_t height;
> +};
> +
> +/*
> + * Request current configuration of the camera:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                | _OP_CONFIG_GET |   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * See response format for this request.
> + *
> + *
> + * Request to set the frame rate of the stream:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                | _FRAME_RATE_SET|   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |                          frame_rate_numer                         | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                          frame_rate_denom                         | 16
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 20
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * frame_rate_numer - uint32_t, numerator of the frame rate.
> + * frame_rate_denom - uint32_t, denominator of the frame rate.
> + *
> + * Notes:
> + *  - to query the current (actual) frame rate use XENCAMERA_OP_CONFIG_GET
> + *    request.
> + *  - this request can be used with camera buffers allocated, but stream
> + *    stopped, e.g. frontend is allowed to stop the stream with
> + *    XENCAMERA_OP_STREAM_STOP, hold the buffers allocated (e.g. keep the
> + *    configuration set with XENCAMERA_OP_CONFIG_SET), change the
> + *    frame rate of the stream and (re)start the stream again with
> + *    XENCAMERA_OP_STREAM_START.
> + *  - frame rate cannot be changed during active streaming, e.g.
> + *    after XENCAMERA_OP_STREAM_START and before XENCAMERA_OP_STREAM_STOP
> + *    commands.
> + */
> +struct xencamera_frame_rate_req {
> +    uint32_t frame_rate_numer;
> +    uint32_t frame_rate_denom;
> +};
> +
> +/*
> + * Request camera buffer's layout:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                | _BUF_GET_LAYOUT|   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * See response format for this request.
> + *
> + *
> + * Request number of buffers to be used:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                | _OP_BUF_REQUEST|   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |    num_bufs    |                     reserved                     | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 16
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * num_bufs - uint8_t, desired number of buffers to be used.
> + *
> + * If num_bufs is not zero then the backend validates the requested number of
> + * buffers and responds with the number of buffers allowed for this frontend.
> + * Frontend is responsible for checking the corresponding response in order to
> + * see if the values reported back by the backend do match the desired ones
> + * and can be accepted.
> + * Frontend is allowed to send multiple XENCAMERA_OP_BUF_REQUEST requests
> + * before sending XENCAMERA_OP_STREAM_START request to update or tune the
> + * final configuration.
> + * Frontend is not allowed to change the camera configuration after this call
> + * with a non-zero value of num_bufs. If camera reconfiguration is required
> + * then this request must be sent with num_bufs set to zero and any created
> + * buffers must be destroyed first.
> + * Frontend is not allowed to change the number of buffers after the
> + * streaming has started.
> + *
> + * If num_bufs is 0 and streaming has not started yet, then the backend will
> + * free all previously allocated buffers (if any).
> + * Trying to call this if streaming is in progress will result in an error.
> + *
> + * If camera reconfiguration is required then the streaming must be stopped
> + * and this request must be sent with num_bufs set to zero and any
> + * created buffers must be destroyed.
> + *
> + * Please note, that the number of buffers in this request must not exceed
> + * the value configured in XenStore.max-buffers.
> + *
> + * See response format for this request.
> + */
> +struct xencamera_buf_request {
> +    uint8_t num_bufs;
> +};
> +
> +/*
> + * Request camera buffer creation:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                | _OP_BUF_CREATE |   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |      index     |                     reserved                     | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                           plane_offset[0]                         | 16
> + * +----------------+----------------+----------------+----------------+
> + * |                           plane_offset[1]                         | 20
> + * +----------------+----------------+----------------+----------------+
> + * |                           plane_offset[2]                         | 24
> + * +----------------+----------------+----------------+----------------+
> + * |                           plane_offset[3]                         | 28
> + * +----------------+----------------+----------------+----------------+
> + * |                           gref_directory                          | 32
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 36
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * An attempt to create multiple buffers with the same index is an error.
> + * index can be re-used after destroying the corresponding camera buffer.
> + *
> + * index - uint8_t, index of the buffer to be created in the range
> + *   from 0 to the num_bufs field returned in response for
> + *   XENCAMERA_OP_BUF_REQUEST request
> + * plane_offset - array of uint32_t, offset of the corresponding plane
> + *   in octets from the buffer start. Number of offsets returned is
> + *   equal to the value returned in XENCAMERA_OP_BUF_GET_LAYOUT.num_planes.
> + * gref_directory - grant_ref_t, a reference to the first shared page
> + *   describing shared buffer references. The size of the buffer is equal to
> + *   XENCAMERA_OP_BUF_GET_LAYOUT.size response. At least one page exists. If
> + *   shared buffer size exceeds what can be addressed by this single page,
> + *   then reference to the next shared page must be supplied (see
> + *   gref_dir_next_page below).
> + *
> + * If XENCAMERA_FIELD_BE_ALLOC configuration entry is set, then backend will
> + * allocate the buffer with the parameters provided in this request and page
> + * directory is handled as follows:
> + *   Frontend on request:
> + *     - allocates pages for the directory (gref_directory,
> + *       gref_dir_next_page(s)
> + *     - grants permissions for the pages of the directory to the backend
> + *     - sets gref_dir_next_page fields
> + *   Backend on response:
> + *     - grants permissions for the pages of the buffer allocated to
> + *       the frontend
> + *     - fills in page directory with grant references
> + *       (gref[] in struct xencamera_page_directory)
> + */
> +struct xencamera_buf_create_req {
> +    uint8_t index;
> +    uint8_t reserved[3];
> +    uint32_t plane_offset[XENCAMERA_MAX_PLANE];
> +    grant_ref_t gref_directory;
> +};
> +
> +/*
> + * Shared page for XENCAMERA_OP_BUF_CREATE buffer descriptor (gref_directory in
> + * the request) employs a list of pages, describing all pages of the shared
> + * data buffer:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |                        gref_dir_next_page                         | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                              gref[0]                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                              gref[i]                              | i*4+8
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             gref[N - 1]                           | N*4+8
> + * +----------------+----------------+----------------+----------------+
> + *
> + * gref_dir_next_page - grant_ref_t, reference to the next page describing
> + *   page directory. Must be 0 if there are no more pages in the list.
> + * gref[i] - grant_ref_t, reference to a shared page of the buffer
> + *   allocated at XENCAMERA_OP_BUF_CREATE.
> + *
> + * Number of grant_ref_t entries in the whole page directory is not
> + * passed, but instead can be calculated as:
> + *   num_grefs_total = (XENCAMERA_OP_BUF_REQUEST.size + XEN_PAGE_SIZE - 1) /
> + *       XEN_PAGE_SIZE
> + */
> +struct xencamera_page_directory {
> +    grant_ref_t gref_dir_next_page;
> +    grant_ref_t gref[1]; /* Variable length */
> +};
> +
> +/*
> + * Request buffer destruction - destroy a previously allocated camera buffer:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                | _OP_BUF_DESTROY|   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |      index     |                     reserved                     | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 16
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * index - uint8_t, index of the buffer to be destroyed.
> + *
> + *
> + * Request queueing of the buffer for backend use:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                | _OP_BUF_QUEUE  |   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |      index     |                     reserved                     | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 16
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * Notes:
> + *  - frontends must not access the buffer content after this request until
> + *    response to XENCAMERA_OP_BUF_DEQUEUE has been received.
> + *  - buffers must be queued to the backend before destroying them with
> + *    XENCAMERA_OP_BUF_DESTROY.
> + *
> + * index - uint8_t, index of the buffer to be queued.
> + *
> + *
> + * Request dequeueing of the buffer for frontend use:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                |_OP_BUF_DEQUEUE |   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |      index     |                     reserved                     | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 16
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * Notes:
> + *  - frontend is allowed to access the buffer content after the corresponding
> + *    response to this request.
> + *
> + * index - uint8_t, index of the buffer to be queued.
> + *
> + *
> + * Request camera control details:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                | _OP_CTRL_ENUM  |   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |      index     |                     reserved                     | 8
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 12
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * See response format for this request.
> + *
> + * index - uint8_t, index of the control to be queried.
> + */
> +struct xencamera_index {
> +    uint8_t index;
> +};
> +
> +/*
> + * Request camera control change:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                |  _OP_SET_CTRL  |   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |       type     |                     reserved                     | 8
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 16
> + * +----------------+----------------+----------------+----------------+
> + * |                          value low 32-bit                         | 20
> + * +----------------+----------------+----------------+----------------+
> + * |                          value high 32-bit                        | 24
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 28
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
> + * value - int64_t, new value of the control.
> + */
> +struct xencamera_ctrl_value {
> +    uint8_t type;
> +    uint8_t reserved[7];
> +    int64_t value;
> +};
> +
> +/*
> + * Request camera control state:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                |  _OP_GET_CTRL  |   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |       type     |                     reserved                     | 8
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 12
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * See response format for this request.
> + *
> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
> + */
> +struct xencamera_get_ctrl_req {
> +    uint8_t type;
> +};
> +
> +/*
> + * Request camera capture stream start:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                |_OP_STREAM_START|   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + *
> + * Request camera capture stream stop:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                |_OP_STREAM_STOP |   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + *
> + *---------------------------------- Responses --------------------------------
> + *
> + * All response packets have the same length (64 octets).
> + *
> + * All response packets have common header:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                |    operation   |    reserved    | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                              status                               | 8
> + * +----------------+----------------+----------------+----------------+
> + *
> + * id - uint16_t, copied from the request.
> + * operation - uint8_t, XENCAMERA_OP_* - copied from request.
> + * status - int32_t, response status, zero on success and -XEN_EXX on failure.
> + *
> + *
> + * Configuration response - response for XENCAMERA_OP_CONFIG_SET,
> + * XENCAMERA_OP_CONFIG_GET and XENCAMERA_OP_CONFIG_VALIDATE requests:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                | _OP_CONFIG_XXX |    reserved    | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                               status                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |                            pixel format                           | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                               width                               | 16
> + * +----------------+----------------+----------------+----------------+
> + * |                               height                              | 20
> + * +----------------+----------------+----------------+----------------+
> + * |                             colorspace                            | 24
> + * +----------------+----------------+----------------+----------------+
> + * |                             xfer_func                             | 28
> + * +----------------+----------------+----------------+----------------+
> + * |                             ycbcr_enc                             | 32
> + * +----------------+----------------+----------------+----------------+
> + * |                            quantization                           | 36
> + * +----------------+----------------+----------------+----------------+
> + * |                       displ_asp_ratio_numer                       | 40
> + * +----------------+----------------+----------------+----------------+
> + * |                       displ_asp_ratio_denom                       | 44
> + * +----------------+----------------+----------------+----------------+
> + * |                          frame_rate_numer                         | 48
> + * +----------------+----------------+----------------+----------------+
> + * |                          frame_rate_denom                         | 52
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 56
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * Meaning of the corresponding values in this response is the same as for
> + * XENCAMERA_OP_CONFIG_SET and XENCAMERA_OP_FRAME_RATE_SET requests.
> + *
> + * colorspace - uint32_t, this supplements pixel_format parameter,
> + *   one of the XENCAMERA_COLORSPACE_XXX.
> + * xfer_func - uint32_t, this supplements colorspace parameter,
> + *   one of the XENCAMERA_XFER_FUNC_XXX.
> + * ycbcr_enc - uint32_t, this supplements colorspace parameter,
> + *   one of the XENCAMERA_YCBCR_ENC_XXX. Please note, that ycbcr_enc is only
> + *   valid for YCbCr pixelformats and should be ignored otherwise.
> + * quantization - uint32_t, this supplements colorspace parameter,
> + *   one of the XENCAMERA_QUANTIZATION_XXX.
> + * displ_asp_ratio_numer - uint32_t, numerator of the display aspect ratio.
> + * displ_asp_ratio_denom - uint32_t, denominator of the display aspect ratio.
> + */
> +struct xencamera_config_resp {
> +    uint32_t pixel_format;
> +    uint32_t width;
> +    uint32_t height;
> +    uint32_t colorspace;
> +    uint32_t xfer_func;
> +    uint32_t ycbcr_enc;
> +    uint32_t quantization;
> +    uint32_t displ_asp_ratio_numer;
> +    uint32_t displ_asp_ratio_denom;
> +    uint32_t frame_rate_numer;
> +    uint32_t frame_rate_denom;
> +};
> +
> +/*
> + * Request buffer response - response for XENCAMERA_OP_BUF_GET_LAYOUT
> + * request:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                |_BUF_GET_LAYOUT |    reserved    | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                               status                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |   num_planes   |                     reserved                     | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                                size                               | 16
> + * +----------------+----------------+----------------+----------------+
> + * |                           plane_size[0]                           | 20
> + * +----------------+----------------+----------------+----------------+
> + * |                           plane_size[1]                           | 24
> + * +----------------+----------------+----------------+----------------+
> + * |                           plane_size[2]                           | 28
> + * +----------------+----------------+----------------+----------------+
> + * |                           plane_size[3]                           | 32
> + * +----------------+----------------+----------------+----------------+
> + * |                          plane_stride[0]                          | 36
> + * +----------------+----------------+----------------+----------------+
> + * |                          plane_stride[1]                          | 40
> + * +----------------+----------------+----------------+----------------+
> + * |                          plane_stride[2]                          | 44
> + * +----------------+----------------+----------------+----------------+
> + * |                          plane_stride[3]                          | 48
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * num_planes - uint8_t, number of planes of the buffer.
> + * size - uint32_t, overall size of the buffer including sizes of the
> + *   individual planes and padding if applicable.
> + * plane_size - array of uint32_t, size in octets of the corresponding plane
> + *   including padding.
> + * plane_stride - array of uint32_t, size in octets occupied by the
> + *   corresponding single image line including padding if applicable.
> + *
> + * Note! The sizes and strides in this response apply to all buffers created
> + * with XENCAMERA_OP_BUF_CREATE command, but individual buffers may have
> + * different plane offsets, see XENCAMERA_OP_BUF_REQUEST.plane_offset.
> + */
> +struct xencamera_buf_get_layout_resp {
> +    uint8_t num_planes;
> +    uint8_t reserved[3];
> +    uint32_t size;
> +    uint32_t plane_size[XENCAMERA_MAX_PLANE];
> +    uint32_t plane_stride[XENCAMERA_MAX_PLANE];
> +};
> +
> +/*
> + * Request buffer response - response for XENCAMERA_OP_BUF_REQUEST
> + * request:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                |_OP_BUF_REQUEST |    reserved    | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                               status                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |   num_buffers  |                     reserved                     | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 16
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * num_buffers - uint8_t, number of buffers to be used.
> + *
> + *
> + * Control enumerate response - response for XENCAMERA_OP_CTRL_ENUM:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                | _OP_CTRL_ENUM  |    reserved    | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                               status                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |     index      |      type      |            reserved             | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                               flags                               | 16
> + * +----------------+----------------+----------------+----------------+
> + * |                          min low 32-bits                          | 20
> + * +----------------+----------------+----------------+----------------+
> + * |                          min high 32-bits                         | 24
> + * +----------------+----------------+----------------+----------------+
> + * |                          max low 32-bits                          | 28
> + * +----------------+----------------+----------------+----------------+
> + * |                          max high 32-bits                         | 32
> + * +----------------+----------------+----------------+----------------+
> + * |                         step low 32-bits                          | 36
> + * +----------------+----------------+----------------+----------------+
> + * |                         step high 32-bits                         | 40
> + * +----------------+----------------+----------------+----------------+
> + * |                        def_val low 32-bits                        | 44
> + * +----------------+----------------+----------------+----------------+
> + * |                        def_val high 32-bits                       | 48
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 52
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * index - uint8_t, index of the camera control in response.
> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
> + * flags - uint32_t, flags of the control, one of the XENCAMERA_CTRL_FLG_XXX.
> + * min - int64_t, minimum value of the control.
> + * max - int64_t, maximum value of the control.
> + * step - int64_t, minimum size in which control value can be changed.
> + * def_val - int64_t, default value of the control.
> + */
> +struct xencamera_ctrl_enum_resp {
> +    uint8_t index;
> +    uint8_t type;
> +    uint8_t reserved[2];
> +    uint32_t flags;
> +    int64_t min;
> +    int64_t max;
> +    int64_t step;
> +    int64_t def_val;
> +};
> +
> +/*
> + * Get control response - response for XENCAMERA_OP_CTRL_GET:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                | _OP_CTRL_GET   |    reserved    | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                               status                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |       type     |                     reserved                     | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 16
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 20
> + * +----------------+----------------+----------------+----------------+
> + * |                          value low 32-bit                         | 24
> + * +----------------+----------------+----------------+----------------+
> + * |                          value high 32-bit                        | 28
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 32
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
> + * value - int64_t, new value of the control.
> + */
> +
> +/*
> + *----------------------------------- Events ----------------------------------
> + *
> + * Events are sent via a shared page allocated by the front and propagated by
> + *   evt-event-channel/evt-ring-ref XenStore entries.
> + *
> + * All event packets have the same length (64 octets).
> + * All event packets have common header:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                |      type      |   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + *
> + * id - uint16_t, event id, may be used by front.
> + * type - uint8_t, type of the event.
> + *
> + *
> + * Frame captured event - event from back to front when a new captured
> + * frame is available:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                |_EVT_FRAME_AVAIL|   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 8
> + * +----------------+----------------+----------------+----------------+
> + * |      index     |                     reserved                     | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                              used_sz                              | 16
> + * +----------------+----------------+----------------+----------------+
> + * |                              seq_num                              | 20
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 24
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * index - uint8_t, index of the buffer that contains new captured frame,
> + *   see XENCAMERA_OP_BUF_CREATE description on the range
> + * used_sz - uint32_t, number of octets this frame has. This can be less
> + * than the XENCAMERA_OP_BUF_REQUEST.size (response) for compressed formats.
> + * seq_num - uint32_t, sequential number of the frame. Must be
> + *   monotonically increasing. If skips are detected in seq_num then that
> + *   means that the frames in-between were dropped. Note however that not
> + *   all video capture hardware is capable of detecting dropped frames.
> + *   In that case there will be no skips in the sequence counter.
> + */
> +struct xencamera_frame_avail_evt {
> +    uint8_t index;
> +    uint8_t reserved[3];
> +    uint32_t used_sz;
> +    uint32_t seq_num;
> +};
> +
> +/*
> + * Control change event- event from back to front when camera control
> + * has changed:
> + *         0                1                 2               3        octet
> + * +----------------+----------------+----------------+----------------+
> + * |               id                |_EVT_CTRL_CHANGE|   reserved     | 4
> + * +----------------+----------------+----------------+----------------+
> + * |       type     |                     reserved                     | 8
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 12
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 16
> + * +----------------+----------------+----------------+----------------+
> + * |                          value low 32-bit                         | 20
> + * +----------------+----------------+----------------+----------------+
> + * |                          value high 32-bit                        | 24
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 28
> + * +----------------+----------------+----------------+----------------+
> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> + * +----------------+----------------+----------------+----------------+
> + * |                             reserved                              | 64
> + * +----------------+----------------+----------------+----------------+
> + *
> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
> + * value - int64_t, new value of the control.
> + *
> + * Notes:
> + *  - this event is not sent for write-only controls
> + *  - this event is not sent to the originator of the control change
> + *  - this event is not sent when frontend first connects, e.g. initial
> + *    control state must be explicitly queried
> + */
> +
> +struct xencamera_req {
> +    uint16_t id;
> +    uint8_t operation;
> +    uint8_t reserved[5];
> +    union {
> +        struct xencamera_config_req config;
> +        struct xencamera_frame_rate_req frame_rate;
> +        struct xencamera_buf_request buf_request;
> +        struct xencamera_buf_create_req buf_create;
> +        struct xencamera_index index;
> +        struct xencamera_ctrl_value ctrl_value;
> +        struct xencamera_get_ctrl_req get_ctrl;
> +        uint8_t reserved[56];
> +    } req;
> +};
> +
> +struct xencamera_resp {
> +    uint16_t id;
> +    uint8_t operation;
> +    uint8_t reserved;
> +    int32_t status;
> +    union {
> +        struct xencamera_config_resp config;
> +        struct xencamera_buf_get_layout_resp buf_layout;
> +        struct xencamera_buf_request buf_request;
> +        struct xencamera_ctrl_enum_resp ctrl_enum;
> +        struct xencamera_ctrl_value ctrl_value;
> +        uint8_t reserved1[56];
> +    } resp;
> +};
> +
> +struct xencamera_evt {
> +    uint16_t id;
> +    uint8_t type;
> +    uint8_t reserved[5];
> +    union {
> +        struct xencamera_frame_avail_evt frame_avail;
> +        struct xencamera_ctrl_value ctrl_value;
> +        uint8_t reserved[56];
> +    } evt;
> +};
> +
> +DEFINE_RING_TYPES(xen_cameraif, struct xencamera_req, struct xencamera_resp);
> +
> +/*
> + ******************************************************************************
> + *                        Back to front events delivery
> + ******************************************************************************
> + * In order to deliver asynchronous events from back to front a shared page is
> + * allocated by front and its granted reference propagated to back via
> + * XenStore entries (evt-ring-ref/evt-event-channel).
> + * This page has a common header used by both front and back to synchronize
> + * access and control event's ring buffer, while back being a producer of the
> + * events and front being a consumer. The rest of the page after the header
> + * is used for event packets.
> + *
> + * Upon reception of an event(s) front may confirm its reception
> + * for either each event, group of events or none.
> + */
> +
> +struct xencamera_event_page {
> +    uint32_t in_cons;
> +    uint32_t in_prod;
> +    uint8_t reserved[56];
> +};
> +
> +#define XENCAMERA_EVENT_PAGE_SIZE 4096
> +#define XENCAMERA_IN_RING_OFFS (sizeof(struct xencamera_event_page))
> +#define XENCAMERA_IN_RING_SIZE (XENCAMERA_EVENT_PAGE_SIZE - XENCAMERA_IN_RING_OFFS)
> +#define XENCAMERA_IN_RING_LEN (XENCAMERA_IN_RING_SIZE / sizeof(struct xencamera_evt))
> +#define XENCAMERA_IN_RING(page) \
> +    ((struct xencamera_evt *)((char *)(page) + XENCAMERA_IN_RING_OFFS))
> +#define XENCAMERA_IN_RING_REF(page, idx) \
> +    (XENCAMERA_IN_RING((page))[(idx) % XENCAMERA_IN_RING_LEN])
> +
> +#endif /* __XEN_PUBLIC_IO_CAMERAIF_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
>
Oleksandr Andrushchenko March 22, 2019, 8:25 a.m. UTC | #2
On 3/22/19 10:22 AM, Hans Verkuil wrote:
> On 3/22/19 8:37 AM, Oleksandr Andrushchenko wrote:
>> From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
>>
>> This is the ABI for the two halves of a para-virtualized
>> camera driver which extends Xen's reach multimedia capabilities even
>> farther enabling it for video conferencing, In-Vehicle Infotainment,
>> high definition maps etc.
>>
>> The initial goal is to support most needed functionality with the
>> final idea to make it possible to extend the protocol if need be:
>>
>> 1. Provide means for base virtual device configuration:
>>   - pixel formats
>>   - resolutions
>>   - frame rates
>> 2. Support basic camera controls:
>>   - contrast
>>   - brightness
>>   - hue
>>   - saturation
>> 3. Support streaming control
>>
>> Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Looks good!
>
> Reviewed-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
>
> Thank you for all your work on this.
This was possible with your great help and support!
I do appreciate this very much!
Thank you
>
> Regards,
>
> 	Hans
>
>> ---
>>   xen/include/public/io/cameraif.h | 1374 ++++++++++++++++++++++++++++++
>>   1 file changed, 1374 insertions(+)
>>   create mode 100644 xen/include/public/io/cameraif.h
>>
>> diff --git a/xen/include/public/io/cameraif.h b/xen/include/public/io/cameraif.h
>> new file mode 100644
>> index 000000000000..acbcbf3bd411
>> --- /dev/null
>> +++ b/xen/include/public/io/cameraif.h
>> @@ -0,0 +1,1374 @@
>> +/******************************************************************************
>> + * cameraif.h
>> + *
>> + * Unified camera device I/O interface for Xen guest OSes.
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a copy
>> + * of this software and associated documentation files (the "Software"), to
>> + * deal in the Software without restriction, including without limitation the
>> + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
>> + * sell copies of the Software, and to permit persons to whom the Software is
>> + * furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be included in
>> + * all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
>> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
>> + * DEALINGS IN THE SOFTWARE.
>> + *
>> + * Copyright (C) 2018-2019 EPAM Systems Inc.
>> + *
>> + * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
>> + */
>> +
>> +#ifndef __XEN_PUBLIC_IO_CAMERAIF_H__
>> +#define __XEN_PUBLIC_IO_CAMERAIF_H__
>> +
>> +#include "ring.h"
>> +#include "../grant_table.h"
>> +
>> +/*
>> + ******************************************************************************
>> + *                           Protocol version
>> + ******************************************************************************
>> + */
>> +#define XENCAMERA_PROTOCOL_VERSION     "1"
>> +
>> +/*
>> + ******************************************************************************
>> + *                  Feature and Parameter Negotiation
>> + ******************************************************************************
>> + *
>> + * Front->back notifications: when enqueuing a new request, sending a
>> + * notification can be made conditional on xencamera_req (i.e., the generic
>> + * hold-off mechanism provided by the ring macros). Backends must set
>> + * xencamera_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()).
>> + *
>> + * Back->front notifications: when enqueuing a new response, sending a
>> + * notification can be made conditional on xencamera_resp (i.e., the generic
>> + * hold-off mechanism provided by the ring macros). Frontends must set
>> + * xencamera_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
>> + *
>> + * The two halves of a para-virtual camera driver utilize nodes within
>> + * XenStore to communicate capabilities and to negotiate operating parameters.
>> + * This section enumerates these nodes which reside in the respective front and
>> + * backend portions of XenStore, following the XenBus convention.
>> + *
>> + * All data in XenStore is stored as strings. Nodes specifying numeric
>> + * values are encoded in decimal. Integer value ranges listed below are
>> + * expressed as fixed sized integer types capable of storing the conversion
>> + * of a properly formatted node string, without loss of information.
>> + *
>> + ******************************************************************************
>> + *                        Example configuration
>> + ******************************************************************************
>> + *
>> + * This is an example of backend and frontend configuration:
>> + *
>> + *--------------------------------- Backend -----------------------------------
>> + *
>> + * /local/domain/0/backend/vcamera/1/0/frontend-id = "1"
>> + * /local/domain/0/backend/vcamera/1/0/frontend = "/local/domain/1/device/vcamera/0"
>> + * /local/domain/0/backend/vcamera/1/0/state = "4"
>> + * /local/domain/0/backend/vcamera/1/0/versions = "1,2"
>> + *
>> + *--------------------------------- Frontend ----------------------------------
>> + *
>> + * /local/domain/1/device/vcamera/0/backend-id = "0"
>> + * /local/domain/1/device/vcamera/0/backend = "/local/domain/0/backend/vcamera/1"
>> + * /local/domain/1/device/vcamera/0/state = "4"
>> + * /local/domain/1/device/vcamera/0/version = "1"
>> + * /local/domain/1/device/vcamera/0/be-alloc = "1"
>> + *
>> + *---------------------------- Device 0 configuration -------------------------
>> + *
>> + * /local/domain/1/device/vcamera/0/max-buffers = "3"
>> + * /local/domain/1/device/vcamera/0/controls = "contrast,hue"
>> + * /local/domain/1/device/vcamera/0/formats/YUYV/640x480/frame-rates = "30/1,15/1"
>> + * /local/domain/1/device/vcamera/0/formats/YUYV/1920x1080/frame-rates = "15/2"
>> + * /local/domain/1/device/vcamera/0/formats/BGRA/640x480/frame-rates = "15/1,15/2"
>> + * /local/domain/1/device/vcamera/0/formats/BGRA/1200x720/frame-rates = "15/2"
>> + * /local/domain/1/device/vcamera/0/unique-id = "0"
>> + * /local/domain/1/device/vcamera/0/req-ring-ref = "2832"
>> + * /local/domain/1/device/vcamera/0/req-event-channel = "15"
>> + * /local/domain/1/device/vcamera/0/evt-ring-ref = "387"
>> + * /local/domain/1/device/vcamera/0/evt-event-channel = "16"
>> + *
>> + *---------------------------- Device 1 configuration -------------------------
>> + *
>> + * /local/domain/1/device/vcamera/1/max-buffers = "8"
>> + * /local/domain/1/device/vcamera/1/controls = "brightness,saturation,hue"
>> + * /local/domain/1/device/vcamera/1/formats/YUYV/640x480/frame-rates = "30/1,15/2"
>> + * /local/domain/1/device/vcamera/1/formats/YUYV/1920x1080/frame-rates = "15/2"
>> + * /local/domain/1/device/vcamera/1/unique-id = "1"
>> + * /local/domain/1/device/vcamera/1/req-ring-ref = "2833"
>> + * /local/domain/1/device/vcamera/1/req-event-channel = "17"
>> + * /local/domain/1/device/vcamera/1/evt-ring-ref = "388"
>> + * /local/domain/1/device/vcamera/1/evt-event-channel = "18"
>> + *
>> + ******************************************************************************
>> + *                            Backend XenBus Nodes
>> + ******************************************************************************
>> + *
>> + *----------------------------- Protocol version ------------------------------
>> + *
>> + * versions
>> + *      Values:         <string>
>> + *
>> + *      List of XENCAMERA_LIST_SEPARATOR separated protocol versions supported
>> + *      by the backend. For example "1,2,3".
>> + *
>> + ******************************************************************************
>> + *                            Frontend XenBus Nodes
>> + ******************************************************************************
>> + *
>> + *-------------------------------- Addressing ---------------------------------
>> + *
>> + * dom-id
>> + *      Values:         <uint16_t>
>> + *
>> + *      Domain identifier.
>> + *
>> + * dev-id
>> + *      Values:         <uint16_t>
>> + *
>> + *      Device identifier.
>> + *
>> + *      /local/domain/<dom-id>/device/vcamera/<dev-id>/...
>> + *
>> + *----------------------------- Protocol version ------------------------------
>> + *
>> + * version
>> + *      Values:         <string>
>> + *
>> + *      Protocol version, chosen among the ones supported by the backend.
>> + *
>> + *------------------------- Backend buffer allocation -------------------------
>> + *
>> + * be-alloc
>> + *      Values:         "0", "1"
>> + *
>> + *      If value is set to "1", then backend will be the buffer
>> + *      provider/allocator for this domain during XENCAMERA_OP_BUF_CREATE
>> + *      operation.
>> + *      If value is not "1" or omitted frontend must allocate buffers itself.
>> + *
>> + *------------------------------- Camera settings -----------------------------
>> + *
>> + * unique-id
>> + *      Values:         <string>
>> + *
>> + *      After device instance initialization each camera is assigned a
>> + *      unique ID, so it can be identified by the backend by this ID.
>> + *      This can be UUID or such.
>> + *
>> + * max-buffers
>> + *      Values:         <uint8_t>
>> + *
>> + *      Maximum number of camera buffers this frontend may use.
>> + *
>> + * controls
>> + *      Values:         <list of string>
>> + *
>> + *      List of supported camera controls separated by XENCAMERA_LIST_SEPARATOR.
>> + *      Camera controls are expressed as a list of string values w/o any
>> + *      ordering requirement.
>> + *
>> + * formats
>> + *      Values:         <format, char[7]>
>> + *
>> + *      Formats are organized as a set of directories one per each
>> + *      supported pixel format. The name of the directory is the
>> + *      corresponding FOURCC string label. The next level of
>> + *      the directory under <formats> represents supported resolutions.
>> + *      If the format represents a big-endian variant of a little
>> + *      endian format, then the "-BE" suffix must be added. E.g. 'AR15' vs
>> + *      'AR15-BE'.
>> + *      If FOURCC string label has spaces then those are only allowed to
>> + *      be at the end of the label and must be trimmed, for example
>> + *      'Y16' and 'Y16-BE' will be trimmed.
>> + *
>> + * resolution
>> + *      Values:         <width, uint32_t>x<height, uint32_t>
>> + *
>> + *      Resolutions are organized as a set of directories one per each
>> + *      supported resolution under corresponding <formats> directory.
>> + *      The name of the directory is the supported width and height
>> + *      of the camera resolution in pixels.
>> + *
>> + * frame-rates
>> + *      Values:         <numerator, uint32_t>/<denominator, uint32_t>
>> + *
>> + *      List of XENCAMERA_FRAME_RATE_SEPARATOR separated supported frame rates
>> + *      of the camera expressed as numerator and denominator of the
>> + *      corresponding frame rate.
>> + *
>> + *------------------- Camera Request Transport Parameters ---------------------
>> + *
>> + * This communication path is used to deliver requests from frontend to backend
>> + * and get the corresponding responses from backend to frontend,
>> + * set up per virtual camera device.
>> + *
>> + * req-event-channel
>> + *      Values:         <uint32_t>
>> + *
>> + *      The identifier of the Xen camera's control event channel
>> + *      used to signal activity in the ring buffer.
>> + *
>> + * req-ring-ref
>> + *      Values:         <uint32_t>
>> + *
>> + *      The Xen grant reference granting permission for the backend to map
>> + *      a sole page of camera's control ring buffer.
>> + *
>> + *-------------------- Camera Event Transport Parameters ----------------------
>> + *
>> + * This communication path is used to deliver asynchronous events from backend
>> + * to frontend, set up per virtual camera device.
>> + *
>> + * evt-event-channel
>> + *      Values:         <uint32_t>
>> + *
>> + *      The identifier of the Xen camera's event channel
>> + *      used to signal activity in the ring buffer.
>> + *
>> + * evt-ring-ref
>> + *      Values:         <uint32_t>
>> + *
>> + *      The Xen grant reference granting permission for the backend to map
>> + *      a sole page of camera's event ring buffer.
>> + */
>> +
>> +/*
>> + ******************************************************************************
>> + *                               STATE DIAGRAMS
>> + ******************************************************************************
>> + *
>> + * Tool stack creates front and back state nodes with initial state
>> + * XenbusStateInitialising.
>> + * Tool stack creates and sets up frontend camera configuration
>> + * nodes per domain.
>> + *
>> + *-------------------------------- Normal flow --------------------------------
>> + *
>> + * Front                                Back
>> + * =================================    =====================================
>> + * XenbusStateInitialising              XenbusStateInitialising
>> + *                                       o Query backend device identification
>> + *                                         data.
>> + *                                       o Open and validate backend device.
>> + *                                                |
>> + *                                                |
>> + *                                                V
>> + *                                      XenbusStateInitWait
>> + *
>> + * o Query frontend configuration
>> + * o Allocate and initialize
>> + *   event channels per configured
>> + *   camera.
>> + * o Publish transport parameters
>> + *   that will be in effect during
>> + *   this connection.
>> + *              |
>> + *              |
>> + *              V
>> + * XenbusStateInitialised
>> + *
>> + *                                       o Query frontend transport parameters.
>> + *                                       o Connect to the event channels.
>> + *                                                |
>> + *                                                |
>> + *                                                V
>> + *                                      XenbusStateConnected
>> + *
>> + *  o Create and initialize OS
>> + *    virtual camera as per
>> + *    configuration.
>> + *              |
>> + *              |
>> + *              V
>> + * XenbusStateConnected
>> + *
>> + *                                      XenbusStateUnknown
>> + *                                      XenbusStateClosed
>> + *                                      XenbusStateClosing
>> + * o Remove virtual camera device
>> + * o Remove event channels
>> + *              |
>> + *              |
>> + *              V
>> + * XenbusStateClosed
>> + *
>> + *------------------------------- Recovery flow -------------------------------
>> + *
>> + * In case of frontend unrecoverable errors backend handles that as
>> + * if frontend goes into the XenbusStateClosed state.
>> + *
>> + * In case of backend unrecoverable errors frontend tries removing
>> + * the virtualized device. If this is possible at the moment of error,
>> + * then frontend goes into the XenbusStateInitialising state and is ready for
>> + * new connection with backend. If the virtualized device is still in use and
>> + * cannot be removed, then frontend goes into the XenbusStateReconfiguring state
>> + * until either the virtualized device is removed or backend initiates a new
>> + * connection. On the virtualized device removal frontend goes into the
>> + * XenbusStateInitialising state.
>> + *
>> + * Note on XenbusStateReconfiguring state of the frontend: if backend has
>> + * unrecoverable errors then frontend cannot send requests to the backend
>> + * and thus cannot provide functionality of the virtualized device anymore.
>> + * After backend is back to normal the virtualized device may still hold some
>> + * state: configuration in use, allocated buffers, client application state etc.
>> + * In most cases, this will require frontend to implement complex recovery
>> + * reconnect logic. Instead, by going into XenbusStateReconfiguring state,
>> + * frontend will make sure no new clients of the virtualized device are
>> + * accepted, allow existing client(s) to exit gracefully by signaling error
>> + * state etc.
>> + * Once all the clients are gone frontend can reinitialize the virtualized
>> + * device and get into XenbusStateInitialising state again signaling the
>> + * backend that a new connection can be made.
>> + *
>> + * There are multiple conditions possible under which frontend will go from
>> + * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS
>> + * specific. For example:
>> + * 1. The underlying OS framework may provide callbacks to signal that the last
>> + *    client of the virtualized device has gone and the device can be removed
>> + * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue)
>> + *    to periodically check if this is the right time to re-try removal of
>> + *    the virtualized device.
>> + * 3. By any other means.
>> + *
>> + ******************************************************************************
>> + *                             REQUEST CODES
>> + ******************************************************************************
>> + */
>> +#define XENCAMERA_OP_CONFIG_SET        0x00
>> +#define XENCAMERA_OP_CONFIG_GET        0x01
>> +#define XENCAMERA_OP_CONFIG_VALIDATE   0x02
>> +#define XENCAMERA_OP_FRAME_RATE_SET    0x03
>> +#define XENCAMERA_OP_BUF_GET_LAYOUT    0x04
>> +#define XENCAMERA_OP_BUF_REQUEST       0x05
>> +#define XENCAMERA_OP_BUF_CREATE        0x06
>> +#define XENCAMERA_OP_BUF_DESTROY       0x07
>> +#define XENCAMERA_OP_BUF_QUEUE         0x08
>> +#define XENCAMERA_OP_BUF_DEQUEUE       0x09
>> +#define XENCAMERA_OP_CTRL_ENUM         0x0a
>> +#define XENCAMERA_OP_CTRL_SET          0x0b
>> +#define XENCAMERA_OP_CTRL_GET          0x0c
>> +#define XENCAMERA_OP_STREAM_START      0x0d
>> +#define XENCAMERA_OP_STREAM_STOP       0x0e
>> +
>> +#define XENCAMERA_CTRL_BRIGHTNESS      0
>> +#define XENCAMERA_CTRL_CONTRAST        1
>> +#define XENCAMERA_CTRL_SATURATION      2
>> +#define XENCAMERA_CTRL_HUE             3
>> +
>> +/* Number of supported controls. */
>> +#define XENCAMERA_MAX_CTRL             4
>> +
>> +/* Control is read-only. */
>> +#define XENCAMERA_CTRL_FLG_RO          (1 << 0)
>> +/* Control is write-only. */
>> +#define XENCAMERA_CTRL_FLG_WO          (1 << 1)
>> +/* Control's value is volatile. */
>> +#define XENCAMERA_CTRL_FLG_VOLATILE    (1 << 2)
>> +
>> +/* Supported color spaces. */
>> +#define XENCAMERA_COLORSPACE_DEFAULT   0
>> +#define XENCAMERA_COLORSPACE_SMPTE170M 1
>> +#define XENCAMERA_COLORSPACE_REC709    2
>> +#define XENCAMERA_COLORSPACE_SRGB      3
>> +#define XENCAMERA_COLORSPACE_OPRGB     4
>> +#define XENCAMERA_COLORSPACE_BT2020    5
>> +#define XENCAMERA_COLORSPACE_DCI_P3    6
>> +
>> +/* Color space transfer function. */
>> +#define XENCAMERA_XFER_FUNC_DEFAULT    0
>> +#define XENCAMERA_XFER_FUNC_709        1
>> +#define XENCAMERA_XFER_FUNC_SRGB       2
>> +#define XENCAMERA_XFER_FUNC_OPRGB      3
>> +#define XENCAMERA_XFER_FUNC_NONE       4
>> +#define XENCAMERA_XFER_FUNC_DCI_P3     5
>> +#define XENCAMERA_XFER_FUNC_SMPTE2084  6
>> +
>> +/* Color space Y’CbCr encoding. */
>> +#define XENCAMERA_YCBCR_ENC_IGNORE           0
>> +#define XENCAMERA_YCBCR_ENC_601              1
>> +#define XENCAMERA_YCBCR_ENC_709              2
>> +#define XENCAMERA_YCBCR_ENC_XV601            3
>> +#define XENCAMERA_YCBCR_ENC_XV709            4
>> +#define XENCAMERA_YCBCR_ENC_BT2020           5
>> +#define XENCAMERA_YCBCR_ENC_BT2020_CONST_LUM 6
>> +
>> +/* Quantization range. */
>> +#define XENCAMERA_QUANTIZATION_DEFAULT       0
>> +#define XENCAMERA_QUANTIZATION_FULL_RANGE    1
>> +#define XENCAMERA_QUANTIZATION_LIM_RANGE     2
>> +
>> +/*
>> + ******************************************************************************
>> + *                                 EVENT CODES
>> + ******************************************************************************
>> + */
>> +#define XENCAMERA_EVT_FRAME_AVAIL      0x00
>> +#define XENCAMERA_EVT_CTRL_CHANGE      0x01
>> +
>> +/*
>> + ******************************************************************************
>> + *               XENSTORE FIELD AND PATH NAME STRINGS, HELPERS
>> + ******************************************************************************
>> + */
>> +#define XENCAMERA_DRIVER_NAME          "vcamera"
>> +
>> +#define XENCAMERA_LIST_SEPARATOR       ","
>> +#define XENCAMERA_RESOLUTION_SEPARATOR "x"
>> +#define XENCAMERA_FRACTION_SEPARATOR   "/"
>> +
>> +#define XENCAMERA_FIELD_BE_VERSIONS    "versions"
>> +#define XENCAMERA_FIELD_FE_VERSION     "version"
>> +#define XENCAMERA_FIELD_REQ_RING_REF   "req-ring-ref"
>> +#define XENCAMERA_FIELD_REQ_CHANNEL    "req-event-channel"
>> +#define XENCAMERA_FIELD_EVT_RING_REF   "evt-ring-ref"
>> +#define XENCAMERA_FIELD_EVT_CHANNEL    "evt-event-channel"
>> +#define XENCAMERA_FIELD_MAX_BUFFERS    "max-buffers"
>> +#define XENCAMERA_FIELD_CONTROLS       "controls"
>> +#define XENCAMERA_FIELD_FORMATS        "formats"
>> +#define XENCAMERA_FIELD_FRAME_RATES    "frame-rates"
>> +#define XENCAMERA_FIELD_BE_ALLOC       "be-alloc"
>> +#define XENCAMERA_FIELD_UNIQUE_ID      "unique-id"
>> +
>> +#define XENCAMERA_CTRL_BRIGHTNESS_STR  "brightness"
>> +#define XENCAMERA_CTRL_CONTRAST_STR    "contrast"
>> +#define XENCAMERA_CTRL_SATURATION_STR  "saturation"
>> +#define XENCAMERA_CTRL_HUE_STR         "hue"
>> +
>> +#define XENCAMERA_FOURCC_BIGENDIAN_STR "-BE"
>> +
>> +/* Maximum number of buffer planes supported. */
>> +#define XENCAMERA_MAX_PLANE            4
>> +
>> +/*
>> + ******************************************************************************
>> + *                          STATUS RETURN CODES
>> + ******************************************************************************
>> + *
>> + * Status return code is zero on success and -XEN_EXX on failure.
>> + *
>> + ******************************************************************************
>> + *                              Assumptions
>> + ******************************************************************************
>> + *
>> + * - usage of grant reference 0 as invalid grant reference:
>> + *   grant reference 0 is valid, but never exposed to a PV driver,
>> + *   because of the fact it is already in use/reserved by the PV console.
>> + * - all references in this document to page sizes must be treated
>> + *   as pages of size XEN_PAGE_SIZE unless otherwise noted.
>> + * - all FOURCC mappings used for configuration and messaging are
>> + *   Linux V4L2 ones: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/videodev2.h
>> + *   with the following exceptions:
>> + *     - characters are allowed in [0x20; 0x7f] range
>> + *     - when used for XenStore configuration entries the following
>> + *       are not allowed:
>> + *       - '/', '\', ' ' (space), '<', '>', ':', '"', '|', '?', '*'
>> + *       - if trailing spaces are part of the FOURCC code then those must be
>> + *         trimmed
>> + *
>> + *
>> + ******************************************************************************
>> + *       Description of the protocol between frontend and backend driver
>> + ******************************************************************************
>> + *
>> + * The two halves of a Para-virtual camera driver communicate with
>> + * each other using shared pages and event channels.
>> + * Shared page contains a ring with request/response packets.
>> + *
>> + * All reserved fields in the structures below must be 0.
>> + *
>> + * For all request/response/event packets:
>> + *   - frame rate parameter is represented as a pair of 4 octet long
>> + *     numerator and denominator:
>> + *       - frame_rate_numer - uint32_t, numerator of the frame rate
>> + *       - frame_rate_denom - uint32_t, denominator of the frame rate
>> + *     The corresponding frame rate (Hz) is calculated as:
>> + *       frame_rate = frame_rate_numer / frame_rate_denom
>> + *   - buffer index is a zero based index of the buffer. Must be less than
>> + *     the value of XENCAMERA_OP_CONFIG_SET.num_bufs response:
>> + *       - index - uint8_t, index of the buffer.
>> + *
>> + *
>> + *---------------------------------- Requests ---------------------------------
>> + *
>> + * All request packets have the same length (64 octets).
>> + * All request packets have common header:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |    operation   |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + *   id - uint16_t, private guest value, echoed in response.
>> + *   operation - uint8_t, operation code, XENCAMERA_OP_XXX.
>> + *
>> + *
>> + * Request to set/validate the configuration - request to set the
>> + * configuration/mode of the camera (XENCAMERA_OP_CONFIG_SET) or to
>> + * check if the configuration is valid and can be used
>> + * (XENCAMERA_OP_CONFIG_VALIDATE):
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_CONFIG_XXX |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                            pixel format                           | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               width                               | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               height                              | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * pixel_format - uint32_t, pixel format to be used, FOURCC code.
>> + * width - uint32_t, width in pixels.
>> + * height - uint32_t, height in pixels.
>> + *
>> + * See response format for this request.
>> + *
>> + * Notes:
>> + *  - the only difference between XENCAMERA_OP_CONFIG_VALIDATE and
>> + *    XENCAMERA_OP_CONFIG_SET is that the former doesn't actually change
>> + *    camera configuration, but queries if the configuration is valid.
>> + *    This can be used while stream is active and/or buffers allocated.
>> + *  - frontend must check the corresponding response in order to see
>> + *    if the values reported back by the backend do match the desired ones
>> + *    and can be accepted.
>> + *  - frontend may send multiple XENCAMERA_OP_CONFIG_SET requests before
>> + *    sending XENCAMERA_OP_STREAM_START request to update or tune the
>> + *    final stream configuration.
>> + *  - configuration cannot be changed during active streaming, e.g.
>> + *    after XENCAMERA_OP_STREAM_START and before XENCAMERA_OP_STREAM_STOP
>> + *    requests.
>> + */
>> +struct xencamera_config_req {
>> +    uint32_t pixel_format;
>> +    uint32_t width;
>> +    uint32_t height;
>> +};
>> +
>> +/*
>> + * Request current configuration of the camera:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_CONFIG_GET |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * See response format for this request.
>> + *
>> + *
>> + * Request to set the frame rate of the stream:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _FRAME_RATE_SET|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          frame_rate_numer                         | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          frame_rate_denom                         | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * frame_rate_numer - uint32_t, numerator of the frame rate.
>> + * frame_rate_denom - uint32_t, denominator of the frame rate.
>> + *
>> + * Notes:
>> + *  - to query the current (actual) frame rate use XENCAMERA_OP_CONFIG_GET
>> + *    request.
>> + *  - this request can be used with camera buffers allocated, but stream
>> + *    stopped, e.g. frontend is allowed to stop the stream with
>> + *    XENCAMERA_OP_STREAM_STOP, hold the buffers allocated (e.g. keep the
>> + *    configuration set with XENCAMERA_OP_CONFIG_SET), change the
>> + *    frame rate of the stream and (re)start the stream again with
>> + *    XENCAMERA_OP_STREAM_START.
>> + *  - frame rate cannot be changed during active streaming, e.g.
>> + *    after XENCAMERA_OP_STREAM_START and before XENCAMERA_OP_STREAM_STOP
>> + *    commands.
>> + */
>> +struct xencamera_frame_rate_req {
>> +    uint32_t frame_rate_numer;
>> +    uint32_t frame_rate_denom;
>> +};
>> +
>> +/*
>> + * Request camera buffer's layout:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _BUF_GET_LAYOUT|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * See response format for this request.
>> + *
>> + *
>> + * Request number of buffers to be used:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_BUF_REQUEST|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |    num_bufs    |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * num_bufs - uint8_t, desired number of buffers to be used.
>> + *
>> + * If num_bufs is not zero then the backend validates the requested number of
>> + * buffers and responds with the number of buffers allowed for this frontend.
>> + * Frontend is responsible for checking the corresponding response in order to
>> + * see if the values reported back by the backend do match the desired ones
>> + * and can be accepted.
>> + * Frontend is allowed to send multiple XENCAMERA_OP_BUF_REQUEST requests
>> + * before sending XENCAMERA_OP_STREAM_START request to update or tune the
>> + * final configuration.
>> + * Frontend is not allowed to change the camera configuration after this call
>> + * with a non-zero value of num_bufs. If camera reconfiguration is required
>> + * then this request must be sent with num_bufs set to zero and any created
>> + * buffers must be destroyed first.
>> + * Frontend is not allowed to change the number of buffers after the
>> + * streaming has started.
>> + *
>> + * If num_bufs is 0 and streaming has not started yet, then the backend will
>> + * free all previously allocated buffers (if any).
>> + * Trying to call this if streaming is in progress will result in an error.
>> + *
>> + * If camera reconfiguration is required then the streaming must be stopped
>> + * and this request must be sent with num_bufs set to zero and any
>> + * created buffers must be destroyed.
>> + *
>> + * Please note, that the number of buffers in this request must not exceed
>> + * the value configured in XenStore.max-buffers.
>> + *
>> + * See response format for this request.
>> + */
>> +struct xencamera_buf_request {
>> +    uint8_t num_bufs;
>> +};
>> +
>> +/*
>> + * Request camera buffer creation:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_BUF_CREATE |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |      index     |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_offset[0]                         | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_offset[1]                         | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_offset[2]                         | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_offset[3]                         | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           gref_directory                          | 32
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 36
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * An attempt to create multiple buffers with the same index is an error.
>> + * index can be re-used after destroying the corresponding camera buffer.
>> + *
>> + * index - uint8_t, index of the buffer to be created in the range
>> + *   from 0 to the num_bufs field returned in response for
>> + *   XENCAMERA_OP_BUF_REQUEST request
>> + * plane_offset - array of uint32_t, offset of the corresponding plane
>> + *   in octets from the buffer start. Number of offsets returned is
>> + *   equal to the value returned in XENCAMERA_OP_BUF_GET_LAYOUT.num_planes.
>> + * gref_directory - grant_ref_t, a reference to the first shared page
>> + *   describing shared buffer references. The size of the buffer is equal to
>> + *   XENCAMERA_OP_BUF_GET_LAYOUT.size response. At least one page exists. If
>> + *   shared buffer size exceeds what can be addressed by this single page,
>> + *   then reference to the next shared page must be supplied (see
>> + *   gref_dir_next_page below).
>> + *
>> + * If XENCAMERA_FIELD_BE_ALLOC configuration entry is set, then backend will
>> + * allocate the buffer with the parameters provided in this request and page
>> + * directory is handled as follows:
>> + *   Frontend on request:
>> + *     - allocates pages for the directory (gref_directory,
>> + *       gref_dir_next_page(s)
>> + *     - grants permissions for the pages of the directory to the backend
>> + *     - sets gref_dir_next_page fields
>> + *   Backend on response:
>> + *     - grants permissions for the pages of the buffer allocated to
>> + *       the frontend
>> + *     - fills in page directory with grant references
>> + *       (gref[] in struct xencamera_page_directory)
>> + */
>> +struct xencamera_buf_create_req {
>> +    uint8_t index;
>> +    uint8_t reserved[3];
>> +    uint32_t plane_offset[XENCAMERA_MAX_PLANE];
>> +    grant_ref_t gref_directory;
>> +};
>> +
>> +/*
>> + * Shared page for XENCAMERA_OP_BUF_CREATE buffer descriptor (gref_directory in
>> + * the request) employs a list of pages, describing all pages of the shared
>> + * data buffer:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |                        gref_dir_next_page                         | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                              gref[0]                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                              gref[i]                              | i*4+8
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             gref[N - 1]                           | N*4+8
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * gref_dir_next_page - grant_ref_t, reference to the next page describing
>> + *   page directory. Must be 0 if there are no more pages in the list.
>> + * gref[i] - grant_ref_t, reference to a shared page of the buffer
>> + *   allocated at XENCAMERA_OP_BUF_CREATE.
>> + *
>> + * Number of grant_ref_t entries in the whole page directory is not
>> + * passed, but instead can be calculated as:
>> + *   num_grefs_total = (XENCAMERA_OP_BUF_REQUEST.size + XEN_PAGE_SIZE - 1) /
>> + *       XEN_PAGE_SIZE
>> + */
>> +struct xencamera_page_directory {
>> +    grant_ref_t gref_dir_next_page;
>> +    grant_ref_t gref[1]; /* Variable length */
>> +};
>> +
>> +/*
>> + * Request buffer destruction - destroy a previously allocated camera buffer:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_BUF_DESTROY|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |      index     |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * index - uint8_t, index of the buffer to be destroyed.
>> + *
>> + *
>> + * Request queueing of the buffer for backend use:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_BUF_QUEUE  |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |      index     |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * Notes:
>> + *  - frontends must not access the buffer content after this request until
>> + *    response to XENCAMERA_OP_BUF_DEQUEUE has been received.
>> + *  - buffers must be queued to the backend before destroying them with
>> + *    XENCAMERA_OP_BUF_DESTROY.
>> + *
>> + * index - uint8_t, index of the buffer to be queued.
>> + *
>> + *
>> + * Request dequeueing of the buffer for frontend use:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_OP_BUF_DEQUEUE |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |      index     |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * Notes:
>> + *  - frontend is allowed to access the buffer content after the corresponding
>> + *    response to this request.
>> + *
>> + * index - uint8_t, index of the buffer to be queued.
>> + *
>> + *
>> + * Request camera control details:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_CTRL_ENUM  |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |      index     |                     reserved                     | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * See response format for this request.
>> + *
>> + * index - uint8_t, index of the control to be queried.
>> + */
>> +struct xencamera_index {
>> +    uint8_t index;
>> +};
>> +
>> +/*
>> + * Request camera control change:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |  _OP_SET_CTRL  |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |       type     |                     reserved                     | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          value low 32-bit                         | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          value high 32-bit                        | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
>> + * value - int64_t, new value of the control.
>> + */
>> +struct xencamera_ctrl_value {
>> +    uint8_t type;
>> +    uint8_t reserved[7];
>> +    int64_t value;
>> +};
>> +
>> +/*
>> + * Request camera control state:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |  _OP_GET_CTRL  |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |       type     |                     reserved                     | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * See response format for this request.
>> + *
>> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
>> + */
>> +struct xencamera_get_ctrl_req {
>> +    uint8_t type;
>> +};
>> +
>> +/*
>> + * Request camera capture stream start:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_OP_STREAM_START|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + *
>> + * Request camera capture stream stop:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_OP_STREAM_STOP |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + *
>> + *---------------------------------- Responses --------------------------------
>> + *
>> + * All response packets have the same length (64 octets).
>> + *
>> + * All response packets have common header:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |    operation   |    reserved    | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                              status                               | 8
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * id - uint16_t, copied from the request.
>> + * operation - uint8_t, XENCAMERA_OP_* - copied from request.
>> + * status - int32_t, response status, zero on success and -XEN_EXX on failure.
>> + *
>> + *
>> + * Configuration response - response for XENCAMERA_OP_CONFIG_SET,
>> + * XENCAMERA_OP_CONFIG_GET and XENCAMERA_OP_CONFIG_VALIDATE requests:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_CONFIG_XXX |    reserved    | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               status                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                            pixel format                           | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               width                               | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               height                              | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             colorspace                            | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             xfer_func                             | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             ycbcr_enc                             | 32
>> + * +----------------+----------------+----------------+----------------+
>> + * |                            quantization                           | 36
>> + * +----------------+----------------+----------------+----------------+
>> + * |                       displ_asp_ratio_numer                       | 40
>> + * +----------------+----------------+----------------+----------------+
>> + * |                       displ_asp_ratio_denom                       | 44
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          frame_rate_numer                         | 48
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          frame_rate_denom                         | 52
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 56
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * Meaning of the corresponding values in this response is the same as for
>> + * XENCAMERA_OP_CONFIG_SET and XENCAMERA_OP_FRAME_RATE_SET requests.
>> + *
>> + * colorspace - uint32_t, this supplements pixel_format parameter,
>> + *   one of the XENCAMERA_COLORSPACE_XXX.
>> + * xfer_func - uint32_t, this supplements colorspace parameter,
>> + *   one of the XENCAMERA_XFER_FUNC_XXX.
>> + * ycbcr_enc - uint32_t, this supplements colorspace parameter,
>> + *   one of the XENCAMERA_YCBCR_ENC_XXX. Please note, that ycbcr_enc is only
>> + *   valid for YCbCr pixelformats and should be ignored otherwise.
>> + * quantization - uint32_t, this supplements colorspace parameter,
>> + *   one of the XENCAMERA_QUANTIZATION_XXX.
>> + * displ_asp_ratio_numer - uint32_t, numerator of the display aspect ratio.
>> + * displ_asp_ratio_denom - uint32_t, denominator of the display aspect ratio.
>> + */
>> +struct xencamera_config_resp {
>> +    uint32_t pixel_format;
>> +    uint32_t width;
>> +    uint32_t height;
>> +    uint32_t colorspace;
>> +    uint32_t xfer_func;
>> +    uint32_t ycbcr_enc;
>> +    uint32_t quantization;
>> +    uint32_t displ_asp_ratio_numer;
>> +    uint32_t displ_asp_ratio_denom;
>> +    uint32_t frame_rate_numer;
>> +    uint32_t frame_rate_denom;
>> +};
>> +
>> +/*
>> + * Request buffer response - response for XENCAMERA_OP_BUF_GET_LAYOUT
>> + * request:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_BUF_GET_LAYOUT |    reserved    | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               status                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |   num_planes   |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                                size                               | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_size[0]                           | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_size[1]                           | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_size[2]                           | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_size[3]                           | 32
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          plane_stride[0]                          | 36
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          plane_stride[1]                          | 40
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          plane_stride[2]                          | 44
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          plane_stride[3]                          | 48
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * num_planes - uint8_t, number of planes of the buffer.
>> + * size - uint32_t, overall size of the buffer including sizes of the
>> + *   individual planes and padding if applicable.
>> + * plane_size - array of uint32_t, size in octets of the corresponding plane
>> + *   including padding.
>> + * plane_stride - array of uint32_t, size in octets occupied by the
>> + *   corresponding single image line including padding if applicable.
>> + *
>> + * Note! The sizes and strides in this response apply to all buffers created
>> + * with XENCAMERA_OP_BUF_CREATE command, but individual buffers may have
>> + * different plane offsets, see XENCAMERA_OP_BUF_REQUEST.plane_offset.
>> + */
>> +struct xencamera_buf_get_layout_resp {
>> +    uint8_t num_planes;
>> +    uint8_t reserved[3];
>> +    uint32_t size;
>> +    uint32_t plane_size[XENCAMERA_MAX_PLANE];
>> +    uint32_t plane_stride[XENCAMERA_MAX_PLANE];
>> +};
>> +
>> +/*
>> + * Request buffer response - response for XENCAMERA_OP_BUF_REQUEST
>> + * request:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_OP_BUF_REQUEST |    reserved    | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               status                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |   num_buffers  |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * num_buffers - uint8_t, number of buffers to be used.
>> + *
>> + *
>> + * Control enumerate response - response for XENCAMERA_OP_CTRL_ENUM:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_CTRL_ENUM  |    reserved    | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               status                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |     index      |      type      |            reserved             | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               flags                               | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          min low 32-bits                          | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          min high 32-bits                         | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          max low 32-bits                          | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          max high 32-bits                         | 32
>> + * +----------------+----------------+----------------+----------------+
>> + * |                         step low 32-bits                          | 36
>> + * +----------------+----------------+----------------+----------------+
>> + * |                         step high 32-bits                         | 40
>> + * +----------------+----------------+----------------+----------------+
>> + * |                        def_val low 32-bits                        | 44
>> + * +----------------+----------------+----------------+----------------+
>> + * |                        def_val high 32-bits                       | 48
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 52
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * index - uint8_t, index of the camera control in response.
>> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
>> + * flags - uint32_t, flags of the control, one of the XENCAMERA_CTRL_FLG_XXX.
>> + * min - int64_t, minimum value of the control.
>> + * max - int64_t, maximum value of the control.
>> + * step - int64_t, minimum size in which control value can be changed.
>> + * def_val - int64_t, default value of the control.
>> + */
>> +struct xencamera_ctrl_enum_resp {
>> +    uint8_t index;
>> +    uint8_t type;
>> +    uint8_t reserved[2];
>> +    uint32_t flags;
>> +    int64_t min;
>> +    int64_t max;
>> +    int64_t step;
>> +    int64_t def_val;
>> +};
>> +
>> +/*
>> + * Get control response - response for XENCAMERA_OP_CTRL_GET:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_CTRL_GET   |    reserved    | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               status                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |       type     |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          value low 32-bit                         | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          value high 32-bit                        | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 32
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
>> + * value - int64_t, new value of the control.
>> + */
>> +
>> +/*
>> + *----------------------------------- Events ----------------------------------
>> + *
>> + * Events are sent via a shared page allocated by the front and propagated by
>> + *   evt-event-channel/evt-ring-ref XenStore entries.
>> + *
>> + * All event packets have the same length (64 octets).
>> + * All event packets have common header:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |      type      |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * id - uint16_t, event id, may be used by front.
>> + * type - uint8_t, type of the event.
>> + *
>> + *
>> + * Frame captured event - event from back to front when a new captured
>> + * frame is available:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_EVT_FRAME_AVAIL|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |      index     |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                              used_sz                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                              seq_num                              | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * index - uint8_t, index of the buffer that contains new captured frame,
>> + *   see XENCAMERA_OP_BUF_CREATE description on the range
>> + * used_sz - uint32_t, number of octets this frame has. This can be less
>> + * than the XENCAMERA_OP_BUF_REQUEST.size (response) for compressed formats.
>> + * seq_num - uint32_t, sequential number of the frame. Must be
>> + *   monotonically increasing. If skips are detected in seq_num then that
>> + *   means that the frames in-between were dropped. Note however that not
>> + *   all video capture hardware is capable of detecting dropped frames.
>> + *   In that case there will be no skips in the sequence counter.
>> + */
>> +struct xencamera_frame_avail_evt {
>> +    uint8_t index;
>> +    uint8_t reserved[3];
>> +    uint32_t used_sz;
>> +    uint32_t seq_num;
>> +};
>> +
>> +/*
>> + * Control change event- event from back to front when camera control
>> + * has changed:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_EVT_CTRL_CHANGE|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |       type     |                     reserved                     | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          value low 32-bit                         | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          value high 32-bit                        | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
>> + * value - int64_t, new value of the control.
>> + *
>> + * Notes:
>> + *  - this event is not sent for write-only controls
>> + *  - this event is not sent to the originator of the control change
>> + *  - this event is not sent when frontend first connects, e.g. initial
>> + *    control state must be explicitly queried
>> + */
>> +
>> +struct xencamera_req {
>> +    uint16_t id;
>> +    uint8_t operation;
>> +    uint8_t reserved[5];
>> +    union {
>> +        struct xencamera_config_req config;
>> +        struct xencamera_frame_rate_req frame_rate;
>> +        struct xencamera_buf_request buf_request;
>> +        struct xencamera_buf_create_req buf_create;
>> +        struct xencamera_index index;
>> +        struct xencamera_ctrl_value ctrl_value;
>> +        struct xencamera_get_ctrl_req get_ctrl;
>> +        uint8_t reserved[56];
>> +    } req;
>> +};
>> +
>> +struct xencamera_resp {
>> +    uint16_t id;
>> +    uint8_t operation;
>> +    uint8_t reserved;
>> +    int32_t status;
>> +    union {
>> +        struct xencamera_config_resp config;
>> +        struct xencamera_buf_get_layout_resp buf_layout;
>> +        struct xencamera_buf_request buf_request;
>> +        struct xencamera_ctrl_enum_resp ctrl_enum;
>> +        struct xencamera_ctrl_value ctrl_value;
>> +        uint8_t reserved1[56];
>> +    } resp;
>> +};
>> +
>> +struct xencamera_evt {
>> +    uint16_t id;
>> +    uint8_t type;
>> +    uint8_t reserved[5];
>> +    union {
>> +        struct xencamera_frame_avail_evt frame_avail;
>> +        struct xencamera_ctrl_value ctrl_value;
>> +        uint8_t reserved[56];
>> +    } evt;
>> +};
>> +
>> +DEFINE_RING_TYPES(xen_cameraif, struct xencamera_req, struct xencamera_resp);
>> +
>> +/*
>> + ******************************************************************************
>> + *                        Back to front events delivery
>> + ******************************************************************************
>> + * In order to deliver asynchronous events from back to front a shared page is
>> + * allocated by front and its granted reference propagated to back via
>> + * XenStore entries (evt-ring-ref/evt-event-channel).
>> + * This page has a common header used by both front and back to synchronize
>> + * access and control event's ring buffer, while back being a producer of the
>> + * events and front being a consumer. The rest of the page after the header
>> + * is used for event packets.
>> + *
>> + * Upon reception of an event(s) front may confirm its reception
>> + * for either each event, group of events or none.
>> + */
>> +
>> +struct xencamera_event_page {
>> +    uint32_t in_cons;
>> +    uint32_t in_prod;
>> +    uint8_t reserved[56];
>> +};
>> +
>> +#define XENCAMERA_EVENT_PAGE_SIZE 4096
>> +#define XENCAMERA_IN_RING_OFFS (sizeof(struct xencamera_event_page))
>> +#define XENCAMERA_IN_RING_SIZE (XENCAMERA_EVENT_PAGE_SIZE - XENCAMERA_IN_RING_OFFS)
>> +#define XENCAMERA_IN_RING_LEN (XENCAMERA_IN_RING_SIZE / sizeof(struct xencamera_evt))
>> +#define XENCAMERA_IN_RING(page) \
>> +    ((struct xencamera_evt *)((char *)(page) + XENCAMERA_IN_RING_OFFS))
>> +#define XENCAMERA_IN_RING_REF(page, idx) \
>> +    (XENCAMERA_IN_RING((page))[(idx) % XENCAMERA_IN_RING_LEN])
>> +
>> +#endif /* __XEN_PUBLIC_IO_CAMERAIF_H__ */
>> +
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * tab-width: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>>
Oleksandr Andrushchenko March 28, 2019, 1:20 p.m. UTC | #3
On 3/22/19 10:22 AM, Hans Verkuil wrote:
> On 3/22/19 8:37 AM, Oleksandr Andrushchenko wrote:
>> From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
>>
>> This is the ABI for the two halves of a para-virtualized
>> camera driver which extends Xen's reach multimedia capabilities even
>> farther enabling it for video conferencing, In-Vehicle Infotainment,
>> high definition maps etc.
>>
>> The initial goal is to support most needed functionality with the
>> final idea to make it possible to extend the protocol if need be:
>>
>> 1. Provide means for base virtual device configuration:
>>   - pixel formats
>>   - resolutions
>>   - frame rates
>> 2. Support basic camera controls:
>>   - contrast
>>   - brightness
>>   - hue
>>   - saturation
>> 3. Support streaming control
>>
>> Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Looks good!
>
> Reviewed-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Juergen,
could you please take a look?
>
> Thank you for all your work on this.
>
> Regards,
>
> 	Hans
>
>> ---
>>   xen/include/public/io/cameraif.h | 1374 ++++++++++++++++++++++++++++++
>>   1 file changed, 1374 insertions(+)
>>   create mode 100644 xen/include/public/io/cameraif.h
>>
>> diff --git a/xen/include/public/io/cameraif.h b/xen/include/public/io/cameraif.h
>> new file mode 100644
>> index 000000000000..acbcbf3bd411
>> --- /dev/null
>> +++ b/xen/include/public/io/cameraif.h
>> @@ -0,0 +1,1374 @@
>> +/******************************************************************************
>> + * cameraif.h
>> + *
>> + * Unified camera device I/O interface for Xen guest OSes.
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a copy
>> + * of this software and associated documentation files (the "Software"), to
>> + * deal in the Software without restriction, including without limitation the
>> + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
>> + * sell copies of the Software, and to permit persons to whom the Software is
>> + * furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be included in
>> + * all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
>> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
>> + * DEALINGS IN THE SOFTWARE.
>> + *
>> + * Copyright (C) 2018-2019 EPAM Systems Inc.
>> + *
>> + * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
>> + */
>> +
>> +#ifndef __XEN_PUBLIC_IO_CAMERAIF_H__
>> +#define __XEN_PUBLIC_IO_CAMERAIF_H__
>> +
>> +#include "ring.h"
>> +#include "../grant_table.h"
>> +
>> +/*
>> + ******************************************************************************
>> + *                           Protocol version
>> + ******************************************************************************
>> + */
>> +#define XENCAMERA_PROTOCOL_VERSION     "1"
>> +
>> +/*
>> + ******************************************************************************
>> + *                  Feature and Parameter Negotiation
>> + ******************************************************************************
>> + *
>> + * Front->back notifications: when enqueuing a new request, sending a
>> + * notification can be made conditional on xencamera_req (i.e., the generic
>> + * hold-off mechanism provided by the ring macros). Backends must set
>> + * xencamera_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()).
>> + *
>> + * Back->front notifications: when enqueuing a new response, sending a
>> + * notification can be made conditional on xencamera_resp (i.e., the generic
>> + * hold-off mechanism provided by the ring macros). Frontends must set
>> + * xencamera_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
>> + *
>> + * The two halves of a para-virtual camera driver utilize nodes within
>> + * XenStore to communicate capabilities and to negotiate operating parameters.
>> + * This section enumerates these nodes which reside in the respective front and
>> + * backend portions of XenStore, following the XenBus convention.
>> + *
>> + * All data in XenStore is stored as strings. Nodes specifying numeric
>> + * values are encoded in decimal. Integer value ranges listed below are
>> + * expressed as fixed sized integer types capable of storing the conversion
>> + * of a properly formatted node string, without loss of information.
>> + *
>> + ******************************************************************************
>> + *                        Example configuration
>> + ******************************************************************************
>> + *
>> + * This is an example of backend and frontend configuration:
>> + *
>> + *--------------------------------- Backend -----------------------------------
>> + *
>> + * /local/domain/0/backend/vcamera/1/0/frontend-id = "1"
>> + * /local/domain/0/backend/vcamera/1/0/frontend = "/local/domain/1/device/vcamera/0"
>> + * /local/domain/0/backend/vcamera/1/0/state = "4"
>> + * /local/domain/0/backend/vcamera/1/0/versions = "1,2"
>> + *
>> + *--------------------------------- Frontend ----------------------------------
>> + *
>> + * /local/domain/1/device/vcamera/0/backend-id = "0"
>> + * /local/domain/1/device/vcamera/0/backend = "/local/domain/0/backend/vcamera/1"
>> + * /local/domain/1/device/vcamera/0/state = "4"
>> + * /local/domain/1/device/vcamera/0/version = "1"
>> + * /local/domain/1/device/vcamera/0/be-alloc = "1"
>> + *
>> + *---------------------------- Device 0 configuration -------------------------
>> + *
>> + * /local/domain/1/device/vcamera/0/max-buffers = "3"
>> + * /local/domain/1/device/vcamera/0/controls = "contrast,hue"
>> + * /local/domain/1/device/vcamera/0/formats/YUYV/640x480/frame-rates = "30/1,15/1"
>> + * /local/domain/1/device/vcamera/0/formats/YUYV/1920x1080/frame-rates = "15/2"
>> + * /local/domain/1/device/vcamera/0/formats/BGRA/640x480/frame-rates = "15/1,15/2"
>> + * /local/domain/1/device/vcamera/0/formats/BGRA/1200x720/frame-rates = "15/2"
>> + * /local/domain/1/device/vcamera/0/unique-id = "0"
>> + * /local/domain/1/device/vcamera/0/req-ring-ref = "2832"
>> + * /local/domain/1/device/vcamera/0/req-event-channel = "15"
>> + * /local/domain/1/device/vcamera/0/evt-ring-ref = "387"
>> + * /local/domain/1/device/vcamera/0/evt-event-channel = "16"
>> + *
>> + *---------------------------- Device 1 configuration -------------------------
>> + *
>> + * /local/domain/1/device/vcamera/1/max-buffers = "8"
>> + * /local/domain/1/device/vcamera/1/controls = "brightness,saturation,hue"
>> + * /local/domain/1/device/vcamera/1/formats/YUYV/640x480/frame-rates = "30/1,15/2"
>> + * /local/domain/1/device/vcamera/1/formats/YUYV/1920x1080/frame-rates = "15/2"
>> + * /local/domain/1/device/vcamera/1/unique-id = "1"
>> + * /local/domain/1/device/vcamera/1/req-ring-ref = "2833"
>> + * /local/domain/1/device/vcamera/1/req-event-channel = "17"
>> + * /local/domain/1/device/vcamera/1/evt-ring-ref = "388"
>> + * /local/domain/1/device/vcamera/1/evt-event-channel = "18"
>> + *
>> + ******************************************************************************
>> + *                            Backend XenBus Nodes
>> + ******************************************************************************
>> + *
>> + *----------------------------- Protocol version ------------------------------
>> + *
>> + * versions
>> + *      Values:         <string>
>> + *
>> + *      List of XENCAMERA_LIST_SEPARATOR separated protocol versions supported
>> + *      by the backend. For example "1,2,3".
>> + *
>> + ******************************************************************************
>> + *                            Frontend XenBus Nodes
>> + ******************************************************************************
>> + *
>> + *-------------------------------- Addressing ---------------------------------
>> + *
>> + * dom-id
>> + *      Values:         <uint16_t>
>> + *
>> + *      Domain identifier.
>> + *
>> + * dev-id
>> + *      Values:         <uint16_t>
>> + *
>> + *      Device identifier.
>> + *
>> + *      /local/domain/<dom-id>/device/vcamera/<dev-id>/...
>> + *
>> + *----------------------------- Protocol version ------------------------------
>> + *
>> + * version
>> + *      Values:         <string>
>> + *
>> + *      Protocol version, chosen among the ones supported by the backend.
>> + *
>> + *------------------------- Backend buffer allocation -------------------------
>> + *
>> + * be-alloc
>> + *      Values:         "0", "1"
>> + *
>> + *      If value is set to "1", then backend will be the buffer
>> + *      provider/allocator for this domain during XENCAMERA_OP_BUF_CREATE
>> + *      operation.
>> + *      If value is not "1" or omitted frontend must allocate buffers itself.
>> + *
>> + *------------------------------- Camera settings -----------------------------
>> + *
>> + * unique-id
>> + *      Values:         <string>
>> + *
>> + *      After device instance initialization each camera is assigned a
>> + *      unique ID, so it can be identified by the backend by this ID.
>> + *      This can be UUID or such.
>> + *
>> + * max-buffers
>> + *      Values:         <uint8_t>
>> + *
>> + *      Maximum number of camera buffers this frontend may use.
>> + *
>> + * controls
>> + *      Values:         <list of string>
>> + *
>> + *      List of supported camera controls separated by XENCAMERA_LIST_SEPARATOR.
>> + *      Camera controls are expressed as a list of string values w/o any
>> + *      ordering requirement.
>> + *
>> + * formats
>> + *      Values:         <format, char[7]>
>> + *
>> + *      Formats are organized as a set of directories one per each
>> + *      supported pixel format. The name of the directory is the
>> + *      corresponding FOURCC string label. The next level of
>> + *      the directory under <formats> represents supported resolutions.
>> + *      If the format represents a big-endian variant of a little
>> + *      endian format, then the "-BE" suffix must be added. E.g. 'AR15' vs
>> + *      'AR15-BE'.
>> + *      If FOURCC string label has spaces then those are only allowed to
>> + *      be at the end of the label and must be trimmed, for example
>> + *      'Y16' and 'Y16-BE' will be trimmed.
>> + *
>> + * resolution
>> + *      Values:         <width, uint32_t>x<height, uint32_t>
>> + *
>> + *      Resolutions are organized as a set of directories one per each
>> + *      supported resolution under corresponding <formats> directory.
>> + *      The name of the directory is the supported width and height
>> + *      of the camera resolution in pixels.
>> + *
>> + * frame-rates
>> + *      Values:         <numerator, uint32_t>/<denominator, uint32_t>
>> + *
>> + *      List of XENCAMERA_FRAME_RATE_SEPARATOR separated supported frame rates
>> + *      of the camera expressed as numerator and denominator of the
>> + *      corresponding frame rate.
>> + *
>> + *------------------- Camera Request Transport Parameters ---------------------
>> + *
>> + * This communication path is used to deliver requests from frontend to backend
>> + * and get the corresponding responses from backend to frontend,
>> + * set up per virtual camera device.
>> + *
>> + * req-event-channel
>> + *      Values:         <uint32_t>
>> + *
>> + *      The identifier of the Xen camera's control event channel
>> + *      used to signal activity in the ring buffer.
>> + *
>> + * req-ring-ref
>> + *      Values:         <uint32_t>
>> + *
>> + *      The Xen grant reference granting permission for the backend to map
>> + *      a sole page of camera's control ring buffer.
>> + *
>> + *-------------------- Camera Event Transport Parameters ----------------------
>> + *
>> + * This communication path is used to deliver asynchronous events from backend
>> + * to frontend, set up per virtual camera device.
>> + *
>> + * evt-event-channel
>> + *      Values:         <uint32_t>
>> + *
>> + *      The identifier of the Xen camera's event channel
>> + *      used to signal activity in the ring buffer.
>> + *
>> + * evt-ring-ref
>> + *      Values:         <uint32_t>
>> + *
>> + *      The Xen grant reference granting permission for the backend to map
>> + *      a sole page of camera's event ring buffer.
>> + */
>> +
>> +/*
>> + ******************************************************************************
>> + *                               STATE DIAGRAMS
>> + ******************************************************************************
>> + *
>> + * Tool stack creates front and back state nodes with initial state
>> + * XenbusStateInitialising.
>> + * Tool stack creates and sets up frontend camera configuration
>> + * nodes per domain.
>> + *
>> + *-------------------------------- Normal flow --------------------------------
>> + *
>> + * Front                                Back
>> + * =================================    =====================================
>> + * XenbusStateInitialising              XenbusStateInitialising
>> + *                                       o Query backend device identification
>> + *                                         data.
>> + *                                       o Open and validate backend device.
>> + *                                                |
>> + *                                                |
>> + *                                                V
>> + *                                      XenbusStateInitWait
>> + *
>> + * o Query frontend configuration
>> + * o Allocate and initialize
>> + *   event channels per configured
>> + *   camera.
>> + * o Publish transport parameters
>> + *   that will be in effect during
>> + *   this connection.
>> + *              |
>> + *              |
>> + *              V
>> + * XenbusStateInitialised
>> + *
>> + *                                       o Query frontend transport parameters.
>> + *                                       o Connect to the event channels.
>> + *                                                |
>> + *                                                |
>> + *                                                V
>> + *                                      XenbusStateConnected
>> + *
>> + *  o Create and initialize OS
>> + *    virtual camera as per
>> + *    configuration.
>> + *              |
>> + *              |
>> + *              V
>> + * XenbusStateConnected
>> + *
>> + *                                      XenbusStateUnknown
>> + *                                      XenbusStateClosed
>> + *                                      XenbusStateClosing
>> + * o Remove virtual camera device
>> + * o Remove event channels
>> + *              |
>> + *              |
>> + *              V
>> + * XenbusStateClosed
>> + *
>> + *------------------------------- Recovery flow -------------------------------
>> + *
>> + * In case of frontend unrecoverable errors backend handles that as
>> + * if frontend goes into the XenbusStateClosed state.
>> + *
>> + * In case of backend unrecoverable errors frontend tries removing
>> + * the virtualized device. If this is possible at the moment of error,
>> + * then frontend goes into the XenbusStateInitialising state and is ready for
>> + * new connection with backend. If the virtualized device is still in use and
>> + * cannot be removed, then frontend goes into the XenbusStateReconfiguring state
>> + * until either the virtualized device is removed or backend initiates a new
>> + * connection. On the virtualized device removal frontend goes into the
>> + * XenbusStateInitialising state.
>> + *
>> + * Note on XenbusStateReconfiguring state of the frontend: if backend has
>> + * unrecoverable errors then frontend cannot send requests to the backend
>> + * and thus cannot provide functionality of the virtualized device anymore.
>> + * After backend is back to normal the virtualized device may still hold some
>> + * state: configuration in use, allocated buffers, client application state etc.
>> + * In most cases, this will require frontend to implement complex recovery
>> + * reconnect logic. Instead, by going into XenbusStateReconfiguring state,
>> + * frontend will make sure no new clients of the virtualized device are
>> + * accepted, allow existing client(s) to exit gracefully by signaling error
>> + * state etc.
>> + * Once all the clients are gone frontend can reinitialize the virtualized
>> + * device and get into XenbusStateInitialising state again signaling the
>> + * backend that a new connection can be made.
>> + *
>> + * There are multiple conditions possible under which frontend will go from
>> + * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS
>> + * specific. For example:
>> + * 1. The underlying OS framework may provide callbacks to signal that the last
>> + *    client of the virtualized device has gone and the device can be removed
>> + * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue)
>> + *    to periodically check if this is the right time to re-try removal of
>> + *    the virtualized device.
>> + * 3. By any other means.
>> + *
>> + ******************************************************************************
>> + *                             REQUEST CODES
>> + ******************************************************************************
>> + */
>> +#define XENCAMERA_OP_CONFIG_SET        0x00
>> +#define XENCAMERA_OP_CONFIG_GET        0x01
>> +#define XENCAMERA_OP_CONFIG_VALIDATE   0x02
>> +#define XENCAMERA_OP_FRAME_RATE_SET    0x03
>> +#define XENCAMERA_OP_BUF_GET_LAYOUT    0x04
>> +#define XENCAMERA_OP_BUF_REQUEST       0x05
>> +#define XENCAMERA_OP_BUF_CREATE        0x06
>> +#define XENCAMERA_OP_BUF_DESTROY       0x07
>> +#define XENCAMERA_OP_BUF_QUEUE         0x08
>> +#define XENCAMERA_OP_BUF_DEQUEUE       0x09
>> +#define XENCAMERA_OP_CTRL_ENUM         0x0a
>> +#define XENCAMERA_OP_CTRL_SET          0x0b
>> +#define XENCAMERA_OP_CTRL_GET          0x0c
>> +#define XENCAMERA_OP_STREAM_START      0x0d
>> +#define XENCAMERA_OP_STREAM_STOP       0x0e
>> +
>> +#define XENCAMERA_CTRL_BRIGHTNESS      0
>> +#define XENCAMERA_CTRL_CONTRAST        1
>> +#define XENCAMERA_CTRL_SATURATION      2
>> +#define XENCAMERA_CTRL_HUE             3
>> +
>> +/* Number of supported controls. */
>> +#define XENCAMERA_MAX_CTRL             4
>> +
>> +/* Control is read-only. */
>> +#define XENCAMERA_CTRL_FLG_RO          (1 << 0)
>> +/* Control is write-only. */
>> +#define XENCAMERA_CTRL_FLG_WO          (1 << 1)
>> +/* Control's value is volatile. */
>> +#define XENCAMERA_CTRL_FLG_VOLATILE    (1 << 2)
>> +
>> +/* Supported color spaces. */
>> +#define XENCAMERA_COLORSPACE_DEFAULT   0
>> +#define XENCAMERA_COLORSPACE_SMPTE170M 1
>> +#define XENCAMERA_COLORSPACE_REC709    2
>> +#define XENCAMERA_COLORSPACE_SRGB      3
>> +#define XENCAMERA_COLORSPACE_OPRGB     4
>> +#define XENCAMERA_COLORSPACE_BT2020    5
>> +#define XENCAMERA_COLORSPACE_DCI_P3    6
>> +
>> +/* Color space transfer function. */
>> +#define XENCAMERA_XFER_FUNC_DEFAULT    0
>> +#define XENCAMERA_XFER_FUNC_709        1
>> +#define XENCAMERA_XFER_FUNC_SRGB       2
>> +#define XENCAMERA_XFER_FUNC_OPRGB      3
>> +#define XENCAMERA_XFER_FUNC_NONE       4
>> +#define XENCAMERA_XFER_FUNC_DCI_P3     5
>> +#define XENCAMERA_XFER_FUNC_SMPTE2084  6
>> +
>> +/* Color space Y’CbCr encoding. */
>> +#define XENCAMERA_YCBCR_ENC_IGNORE           0
>> +#define XENCAMERA_YCBCR_ENC_601              1
>> +#define XENCAMERA_YCBCR_ENC_709              2
>> +#define XENCAMERA_YCBCR_ENC_XV601            3
>> +#define XENCAMERA_YCBCR_ENC_XV709            4
>> +#define XENCAMERA_YCBCR_ENC_BT2020           5
>> +#define XENCAMERA_YCBCR_ENC_BT2020_CONST_LUM 6
>> +
>> +/* Quantization range. */
>> +#define XENCAMERA_QUANTIZATION_DEFAULT       0
>> +#define XENCAMERA_QUANTIZATION_FULL_RANGE    1
>> +#define XENCAMERA_QUANTIZATION_LIM_RANGE     2
>> +
>> +/*
>> + ******************************************************************************
>> + *                                 EVENT CODES
>> + ******************************************************************************
>> + */
>> +#define XENCAMERA_EVT_FRAME_AVAIL      0x00
>> +#define XENCAMERA_EVT_CTRL_CHANGE      0x01
>> +
>> +/*
>> + ******************************************************************************
>> + *               XENSTORE FIELD AND PATH NAME STRINGS, HELPERS
>> + ******************************************************************************
>> + */
>> +#define XENCAMERA_DRIVER_NAME          "vcamera"
>> +
>> +#define XENCAMERA_LIST_SEPARATOR       ","
>> +#define XENCAMERA_RESOLUTION_SEPARATOR "x"
>> +#define XENCAMERA_FRACTION_SEPARATOR   "/"
>> +
>> +#define XENCAMERA_FIELD_BE_VERSIONS    "versions"
>> +#define XENCAMERA_FIELD_FE_VERSION     "version"
>> +#define XENCAMERA_FIELD_REQ_RING_REF   "req-ring-ref"
>> +#define XENCAMERA_FIELD_REQ_CHANNEL    "req-event-channel"
>> +#define XENCAMERA_FIELD_EVT_RING_REF   "evt-ring-ref"
>> +#define XENCAMERA_FIELD_EVT_CHANNEL    "evt-event-channel"
>> +#define XENCAMERA_FIELD_MAX_BUFFERS    "max-buffers"
>> +#define XENCAMERA_FIELD_CONTROLS       "controls"
>> +#define XENCAMERA_FIELD_FORMATS        "formats"
>> +#define XENCAMERA_FIELD_FRAME_RATES    "frame-rates"
>> +#define XENCAMERA_FIELD_BE_ALLOC       "be-alloc"
>> +#define XENCAMERA_FIELD_UNIQUE_ID      "unique-id"
>> +
>> +#define XENCAMERA_CTRL_BRIGHTNESS_STR  "brightness"
>> +#define XENCAMERA_CTRL_CONTRAST_STR    "contrast"
>> +#define XENCAMERA_CTRL_SATURATION_STR  "saturation"
>> +#define XENCAMERA_CTRL_HUE_STR         "hue"
>> +
>> +#define XENCAMERA_FOURCC_BIGENDIAN_STR "-BE"
>> +
>> +/* Maximum number of buffer planes supported. */
>> +#define XENCAMERA_MAX_PLANE            4
>> +
>> +/*
>> + ******************************************************************************
>> + *                          STATUS RETURN CODES
>> + ******************************************************************************
>> + *
>> + * Status return code is zero on success and -XEN_EXX on failure.
>> + *
>> + ******************************************************************************
>> + *                              Assumptions
>> + ******************************************************************************
>> + *
>> + * - usage of grant reference 0 as invalid grant reference:
>> + *   grant reference 0 is valid, but never exposed to a PV driver,
>> + *   because of the fact it is already in use/reserved by the PV console.
>> + * - all references in this document to page sizes must be treated
>> + *   as pages of size XEN_PAGE_SIZE unless otherwise noted.
>> + * - all FOURCC mappings used for configuration and messaging are
>> + *   Linux V4L2 ones: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/videodev2.h
>> + *   with the following exceptions:
>> + *     - characters are allowed in [0x20; 0x7f] range
>> + *     - when used for XenStore configuration entries the following
>> + *       are not allowed:
>> + *       - '/', '\', ' ' (space), '<', '>', ':', '"', '|', '?', '*'
>> + *       - if trailing spaces are part of the FOURCC code then those must be
>> + *         trimmed
>> + *
>> + *
>> + ******************************************************************************
>> + *       Description of the protocol between frontend and backend driver
>> + ******************************************************************************
>> + *
>> + * The two halves of a Para-virtual camera driver communicate with
>> + * each other using shared pages and event channels.
>> + * Shared page contains a ring with request/response packets.
>> + *
>> + * All reserved fields in the structures below must be 0.
>> + *
>> + * For all request/response/event packets:
>> + *   - frame rate parameter is represented as a pair of 4 octet long
>> + *     numerator and denominator:
>> + *       - frame_rate_numer - uint32_t, numerator of the frame rate
>> + *       - frame_rate_denom - uint32_t, denominator of the frame rate
>> + *     The corresponding frame rate (Hz) is calculated as:
>> + *       frame_rate = frame_rate_numer / frame_rate_denom
>> + *   - buffer index is a zero based index of the buffer. Must be less than
>> + *     the value of XENCAMERA_OP_CONFIG_SET.num_bufs response:
>> + *       - index - uint8_t, index of the buffer.
>> + *
>> + *
>> + *---------------------------------- Requests ---------------------------------
>> + *
>> + * All request packets have the same length (64 octets).
>> + * All request packets have common header:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |    operation   |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + *   id - uint16_t, private guest value, echoed in response.
>> + *   operation - uint8_t, operation code, XENCAMERA_OP_XXX.
>> + *
>> + *
>> + * Request to set/validate the configuration - request to set the
>> + * configuration/mode of the camera (XENCAMERA_OP_CONFIG_SET) or to
>> + * check if the configuration is valid and can be used
>> + * (XENCAMERA_OP_CONFIG_VALIDATE):
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_CONFIG_XXX |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                            pixel format                           | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               width                               | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               height                              | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * pixel_format - uint32_t, pixel format to be used, FOURCC code.
>> + * width - uint32_t, width in pixels.
>> + * height - uint32_t, height in pixels.
>> + *
>> + * See response format for this request.
>> + *
>> + * Notes:
>> + *  - the only difference between XENCAMERA_OP_CONFIG_VALIDATE and
>> + *    XENCAMERA_OP_CONFIG_SET is that the former doesn't actually change
>> + *    camera configuration, but queries if the configuration is valid.
>> + *    This can be used while stream is active and/or buffers allocated.
>> + *  - frontend must check the corresponding response in order to see
>> + *    if the values reported back by the backend do match the desired ones
>> + *    and can be accepted.
>> + *  - frontend may send multiple XENCAMERA_OP_CONFIG_SET requests before
>> + *    sending XENCAMERA_OP_STREAM_START request to update or tune the
>> + *    final stream configuration.
>> + *  - configuration cannot be changed during active streaming, e.g.
>> + *    after XENCAMERA_OP_STREAM_START and before XENCAMERA_OP_STREAM_STOP
>> + *    requests.
>> + */
>> +struct xencamera_config_req {
>> +    uint32_t pixel_format;
>> +    uint32_t width;
>> +    uint32_t height;
>> +};
>> +
>> +/*
>> + * Request current configuration of the camera:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_CONFIG_GET |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * See response format for this request.
>> + *
>> + *
>> + * Request to set the frame rate of the stream:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _FRAME_RATE_SET|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          frame_rate_numer                         | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          frame_rate_denom                         | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * frame_rate_numer - uint32_t, numerator of the frame rate.
>> + * frame_rate_denom - uint32_t, denominator of the frame rate.
>> + *
>> + * Notes:
>> + *  - to query the current (actual) frame rate use XENCAMERA_OP_CONFIG_GET
>> + *    request.
>> + *  - this request can be used with camera buffers allocated, but stream
>> + *    stopped, e.g. frontend is allowed to stop the stream with
>> + *    XENCAMERA_OP_STREAM_STOP, hold the buffers allocated (e.g. keep the
>> + *    configuration set with XENCAMERA_OP_CONFIG_SET), change the
>> + *    frame rate of the stream and (re)start the stream again with
>> + *    XENCAMERA_OP_STREAM_START.
>> + *  - frame rate cannot be changed during active streaming, e.g.
>> + *    after XENCAMERA_OP_STREAM_START and before XENCAMERA_OP_STREAM_STOP
>> + *    commands.
>> + */
>> +struct xencamera_frame_rate_req {
>> +    uint32_t frame_rate_numer;
>> +    uint32_t frame_rate_denom;
>> +};
>> +
>> +/*
>> + * Request camera buffer's layout:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _BUF_GET_LAYOUT|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * See response format for this request.
>> + *
>> + *
>> + * Request number of buffers to be used:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_BUF_REQUEST|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |    num_bufs    |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * num_bufs - uint8_t, desired number of buffers to be used.
>> + *
>> + * If num_bufs is not zero then the backend validates the requested number of
>> + * buffers and responds with the number of buffers allowed for this frontend.
>> + * Frontend is responsible for checking the corresponding response in order to
>> + * see if the values reported back by the backend do match the desired ones
>> + * and can be accepted.
>> + * Frontend is allowed to send multiple XENCAMERA_OP_BUF_REQUEST requests
>> + * before sending XENCAMERA_OP_STREAM_START request to update or tune the
>> + * final configuration.
>> + * Frontend is not allowed to change the camera configuration after this call
>> + * with a non-zero value of num_bufs. If camera reconfiguration is required
>> + * then this request must be sent with num_bufs set to zero and any created
>> + * buffers must be destroyed first.
>> + * Frontend is not allowed to change the number of buffers after the
>> + * streaming has started.
>> + *
>> + * If num_bufs is 0 and streaming has not started yet, then the backend will
>> + * free all previously allocated buffers (if any).
>> + * Trying to call this if streaming is in progress will result in an error.
>> + *
>> + * If camera reconfiguration is required then the streaming must be stopped
>> + * and this request must be sent with num_bufs set to zero and any
>> + * created buffers must be destroyed.
>> + *
>> + * Please note, that the number of buffers in this request must not exceed
>> + * the value configured in XenStore.max-buffers.
>> + *
>> + * See response format for this request.
>> + */
>> +struct xencamera_buf_request {
>> +    uint8_t num_bufs;
>> +};
>> +
>> +/*
>> + * Request camera buffer creation:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_BUF_CREATE |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |      index     |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_offset[0]                         | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_offset[1]                         | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_offset[2]                         | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_offset[3]                         | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           gref_directory                          | 32
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 36
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * An attempt to create multiple buffers with the same index is an error.
>> + * index can be re-used after destroying the corresponding camera buffer.
>> + *
>> + * index - uint8_t, index of the buffer to be created in the range
>> + *   from 0 to the num_bufs field returned in response for
>> + *   XENCAMERA_OP_BUF_REQUEST request
>> + * plane_offset - array of uint32_t, offset of the corresponding plane
>> + *   in octets from the buffer start. Number of offsets returned is
>> + *   equal to the value returned in XENCAMERA_OP_BUF_GET_LAYOUT.num_planes.
>> + * gref_directory - grant_ref_t, a reference to the first shared page
>> + *   describing shared buffer references. The size of the buffer is equal to
>> + *   XENCAMERA_OP_BUF_GET_LAYOUT.size response. At least one page exists. If
>> + *   shared buffer size exceeds what can be addressed by this single page,
>> + *   then reference to the next shared page must be supplied (see
>> + *   gref_dir_next_page below).
>> + *
>> + * If XENCAMERA_FIELD_BE_ALLOC configuration entry is set, then backend will
>> + * allocate the buffer with the parameters provided in this request and page
>> + * directory is handled as follows:
>> + *   Frontend on request:
>> + *     - allocates pages for the directory (gref_directory,
>> + *       gref_dir_next_page(s)
>> + *     - grants permissions for the pages of the directory to the backend
>> + *     - sets gref_dir_next_page fields
>> + *   Backend on response:
>> + *     - grants permissions for the pages of the buffer allocated to
>> + *       the frontend
>> + *     - fills in page directory with grant references
>> + *       (gref[] in struct xencamera_page_directory)
>> + */
>> +struct xencamera_buf_create_req {
>> +    uint8_t index;
>> +    uint8_t reserved[3];
>> +    uint32_t plane_offset[XENCAMERA_MAX_PLANE];
>> +    grant_ref_t gref_directory;
>> +};
>> +
>> +/*
>> + * Shared page for XENCAMERA_OP_BUF_CREATE buffer descriptor (gref_directory in
>> + * the request) employs a list of pages, describing all pages of the shared
>> + * data buffer:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |                        gref_dir_next_page                         | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                              gref[0]                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                              gref[i]                              | i*4+8
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             gref[N - 1]                           | N*4+8
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * gref_dir_next_page - grant_ref_t, reference to the next page describing
>> + *   page directory. Must be 0 if there are no more pages in the list.
>> + * gref[i] - grant_ref_t, reference to a shared page of the buffer
>> + *   allocated at XENCAMERA_OP_BUF_CREATE.
>> + *
>> + * Number of grant_ref_t entries in the whole page directory is not
>> + * passed, but instead can be calculated as:
>> + *   num_grefs_total = (XENCAMERA_OP_BUF_REQUEST.size + XEN_PAGE_SIZE - 1) /
>> + *       XEN_PAGE_SIZE
>> + */
>> +struct xencamera_page_directory {
>> +    grant_ref_t gref_dir_next_page;
>> +    grant_ref_t gref[1]; /* Variable length */
>> +};
>> +
>> +/*
>> + * Request buffer destruction - destroy a previously allocated camera buffer:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_BUF_DESTROY|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |      index     |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * index - uint8_t, index of the buffer to be destroyed.
>> + *
>> + *
>> + * Request queueing of the buffer for backend use:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_BUF_QUEUE  |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |      index     |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * Notes:
>> + *  - frontends must not access the buffer content after this request until
>> + *    response to XENCAMERA_OP_BUF_DEQUEUE has been received.
>> + *  - buffers must be queued to the backend before destroying them with
>> + *    XENCAMERA_OP_BUF_DESTROY.
>> + *
>> + * index - uint8_t, index of the buffer to be queued.
>> + *
>> + *
>> + * Request dequeueing of the buffer for frontend use:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_OP_BUF_DEQUEUE |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |      index     |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * Notes:
>> + *  - frontend is allowed to access the buffer content after the corresponding
>> + *    response to this request.
>> + *
>> + * index - uint8_t, index of the buffer to be queued.
>> + *
>> + *
>> + * Request camera control details:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_CTRL_ENUM  |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |      index     |                     reserved                     | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * See response format for this request.
>> + *
>> + * index - uint8_t, index of the control to be queried.
>> + */
>> +struct xencamera_index {
>> +    uint8_t index;
>> +};
>> +
>> +/*
>> + * Request camera control change:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |  _OP_SET_CTRL  |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |       type     |                     reserved                     | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          value low 32-bit                         | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          value high 32-bit                        | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
>> + * value - int64_t, new value of the control.
>> + */
>> +struct xencamera_ctrl_value {
>> +    uint8_t type;
>> +    uint8_t reserved[7];
>> +    int64_t value;
>> +};
>> +
>> +/*
>> + * Request camera control state:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |  _OP_GET_CTRL  |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |       type     |                     reserved                     | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * See response format for this request.
>> + *
>> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
>> + */
>> +struct xencamera_get_ctrl_req {
>> +    uint8_t type;
>> +};
>> +
>> +/*
>> + * Request camera capture stream start:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_OP_STREAM_START|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + *
>> + * Request camera capture stream stop:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_OP_STREAM_STOP |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + *
>> + *---------------------------------- Responses --------------------------------
>> + *
>> + * All response packets have the same length (64 octets).
>> + *
>> + * All response packets have common header:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |    operation   |    reserved    | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                              status                               | 8
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * id - uint16_t, copied from the request.
>> + * operation - uint8_t, XENCAMERA_OP_* - copied from request.
>> + * status - int32_t, response status, zero on success and -XEN_EXX on failure.
>> + *
>> + *
>> + * Configuration response - response for XENCAMERA_OP_CONFIG_SET,
>> + * XENCAMERA_OP_CONFIG_GET and XENCAMERA_OP_CONFIG_VALIDATE requests:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_CONFIG_XXX |    reserved    | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               status                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                            pixel format                           | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               width                               | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               height                              | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             colorspace                            | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             xfer_func                             | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             ycbcr_enc                             | 32
>> + * +----------------+----------------+----------------+----------------+
>> + * |                            quantization                           | 36
>> + * +----------------+----------------+----------------+----------------+
>> + * |                       displ_asp_ratio_numer                       | 40
>> + * +----------------+----------------+----------------+----------------+
>> + * |                       displ_asp_ratio_denom                       | 44
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          frame_rate_numer                         | 48
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          frame_rate_denom                         | 52
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 56
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * Meaning of the corresponding values in this response is the same as for
>> + * XENCAMERA_OP_CONFIG_SET and XENCAMERA_OP_FRAME_RATE_SET requests.
>> + *
>> + * colorspace - uint32_t, this supplements pixel_format parameter,
>> + *   one of the XENCAMERA_COLORSPACE_XXX.
>> + * xfer_func - uint32_t, this supplements colorspace parameter,
>> + *   one of the XENCAMERA_XFER_FUNC_XXX.
>> + * ycbcr_enc - uint32_t, this supplements colorspace parameter,
>> + *   one of the XENCAMERA_YCBCR_ENC_XXX. Please note, that ycbcr_enc is only
>> + *   valid for YCbCr pixelformats and should be ignored otherwise.
>> + * quantization - uint32_t, this supplements colorspace parameter,
>> + *   one of the XENCAMERA_QUANTIZATION_XXX.
>> + * displ_asp_ratio_numer - uint32_t, numerator of the display aspect ratio.
>> + * displ_asp_ratio_denom - uint32_t, denominator of the display aspect ratio.
>> + */
>> +struct xencamera_config_resp {
>> +    uint32_t pixel_format;
>> +    uint32_t width;
>> +    uint32_t height;
>> +    uint32_t colorspace;
>> +    uint32_t xfer_func;
>> +    uint32_t ycbcr_enc;
>> +    uint32_t quantization;
>> +    uint32_t displ_asp_ratio_numer;
>> +    uint32_t displ_asp_ratio_denom;
>> +    uint32_t frame_rate_numer;
>> +    uint32_t frame_rate_denom;
>> +};
>> +
>> +/*
>> + * Request buffer response - response for XENCAMERA_OP_BUF_GET_LAYOUT
>> + * request:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_BUF_GET_LAYOUT |    reserved    | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               status                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |   num_planes   |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                                size                               | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_size[0]                           | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_size[1]                           | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_size[2]                           | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |                           plane_size[3]                           | 32
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          plane_stride[0]                          | 36
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          plane_stride[1]                          | 40
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          plane_stride[2]                          | 44
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          plane_stride[3]                          | 48
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * num_planes - uint8_t, number of planes of the buffer.
>> + * size - uint32_t, overall size of the buffer including sizes of the
>> + *   individual planes and padding if applicable.
>> + * plane_size - array of uint32_t, size in octets of the corresponding plane
>> + *   including padding.
>> + * plane_stride - array of uint32_t, size in octets occupied by the
>> + *   corresponding single image line including padding if applicable.
>> + *
>> + * Note! The sizes and strides in this response apply to all buffers created
>> + * with XENCAMERA_OP_BUF_CREATE command, but individual buffers may have
>> + * different plane offsets, see XENCAMERA_OP_BUF_REQUEST.plane_offset.
>> + */
>> +struct xencamera_buf_get_layout_resp {
>> +    uint8_t num_planes;
>> +    uint8_t reserved[3];
>> +    uint32_t size;
>> +    uint32_t plane_size[XENCAMERA_MAX_PLANE];
>> +    uint32_t plane_stride[XENCAMERA_MAX_PLANE];
>> +};
>> +
>> +/*
>> + * Request buffer response - response for XENCAMERA_OP_BUF_REQUEST
>> + * request:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_OP_BUF_REQUEST |    reserved    | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               status                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |   num_buffers  |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * num_buffers - uint8_t, number of buffers to be used.
>> + *
>> + *
>> + * Control enumerate response - response for XENCAMERA_OP_CTRL_ENUM:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_CTRL_ENUM  |    reserved    | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               status                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |     index      |      type      |            reserved             | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               flags                               | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          min low 32-bits                          | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          min high 32-bits                         | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          max low 32-bits                          | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          max high 32-bits                         | 32
>> + * +----------------+----------------+----------------+----------------+
>> + * |                         step low 32-bits                          | 36
>> + * +----------------+----------------+----------------+----------------+
>> + * |                         step high 32-bits                         | 40
>> + * +----------------+----------------+----------------+----------------+
>> + * |                        def_val low 32-bits                        | 44
>> + * +----------------+----------------+----------------+----------------+
>> + * |                        def_val high 32-bits                       | 48
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 52
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * index - uint8_t, index of the camera control in response.
>> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
>> + * flags - uint32_t, flags of the control, one of the XENCAMERA_CTRL_FLG_XXX.
>> + * min - int64_t, minimum value of the control.
>> + * max - int64_t, maximum value of the control.
>> + * step - int64_t, minimum size in which control value can be changed.
>> + * def_val - int64_t, default value of the control.
>> + */
>> +struct xencamera_ctrl_enum_resp {
>> +    uint8_t index;
>> +    uint8_t type;
>> +    uint8_t reserved[2];
>> +    uint32_t flags;
>> +    int64_t min;
>> +    int64_t max;
>> +    int64_t step;
>> +    int64_t def_val;
>> +};
>> +
>> +/*
>> + * Get control response - response for XENCAMERA_OP_CTRL_GET:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                | _OP_CTRL_GET   |    reserved    | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                               status                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |       type     |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          value low 32-bit                         | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          value high 32-bit                        | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 32
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
>> + * value - int64_t, new value of the control.
>> + */
>> +
>> +/*
>> + *----------------------------------- Events ----------------------------------
>> + *
>> + * Events are sent via a shared page allocated by the front and propagated by
>> + *   evt-event-channel/evt-ring-ref XenStore entries.
>> + *
>> + * All event packets have the same length (64 octets).
>> + * All event packets have common header:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |      type      |   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * id - uint16_t, event id, may be used by front.
>> + * type - uint8_t, type of the event.
>> + *
>> + *
>> + * Frame captured event - event from back to front when a new captured
>> + * frame is available:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_EVT_FRAME_AVAIL|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |      index     |                     reserved                     | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                              used_sz                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                              seq_num                              | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * index - uint8_t, index of the buffer that contains new captured frame,
>> + *   see XENCAMERA_OP_BUF_CREATE description on the range
>> + * used_sz - uint32_t, number of octets this frame has. This can be less
>> + * than the XENCAMERA_OP_BUF_REQUEST.size (response) for compressed formats.
>> + * seq_num - uint32_t, sequential number of the frame. Must be
>> + *   monotonically increasing. If skips are detected in seq_num then that
>> + *   means that the frames in-between were dropped. Note however that not
>> + *   all video capture hardware is capable of detecting dropped frames.
>> + *   In that case there will be no skips in the sequence counter.
>> + */
>> +struct xencamera_frame_avail_evt {
>> +    uint8_t index;
>> +    uint8_t reserved[3];
>> +    uint32_t used_sz;
>> +    uint32_t seq_num;
>> +};
>> +
>> +/*
>> + * Control change event- event from back to front when camera control
>> + * has changed:
>> + *         0                1                 2               3        octet
>> + * +----------------+----------------+----------------+----------------+
>> + * |               id                |_EVT_CTRL_CHANGE|   reserved     | 4
>> + * +----------------+----------------+----------------+----------------+
>> + * |       type     |                     reserved                     | 8
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 12
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 16
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          value low 32-bit                         | 20
>> + * +----------------+----------------+----------------+----------------+
>> + * |                          value high 32-bit                        | 24
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 28
>> + * +----------------+----------------+----------------+----------------+
>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>> + * +----------------+----------------+----------------+----------------+
>> + * |                             reserved                              | 64
>> + * +----------------+----------------+----------------+----------------+
>> + *
>> + * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
>> + * value - int64_t, new value of the control.
>> + *
>> + * Notes:
>> + *  - this event is not sent for write-only controls
>> + *  - this event is not sent to the originator of the control change
>> + *  - this event is not sent when frontend first connects, e.g. initial
>> + *    control state must be explicitly queried
>> + */
>> +
>> +struct xencamera_req {
>> +    uint16_t id;
>> +    uint8_t operation;
>> +    uint8_t reserved[5];
>> +    union {
>> +        struct xencamera_config_req config;
>> +        struct xencamera_frame_rate_req frame_rate;
>> +        struct xencamera_buf_request buf_request;
>> +        struct xencamera_buf_create_req buf_create;
>> +        struct xencamera_index index;
>> +        struct xencamera_ctrl_value ctrl_value;
>> +        struct xencamera_get_ctrl_req get_ctrl;
>> +        uint8_t reserved[56];
>> +    } req;
>> +};
>> +
>> +struct xencamera_resp {
>> +    uint16_t id;
>> +    uint8_t operation;
>> +    uint8_t reserved;
>> +    int32_t status;
>> +    union {
>> +        struct xencamera_config_resp config;
>> +        struct xencamera_buf_get_layout_resp buf_layout;
>> +        struct xencamera_buf_request buf_request;
>> +        struct xencamera_ctrl_enum_resp ctrl_enum;
>> +        struct xencamera_ctrl_value ctrl_value;
>> +        uint8_t reserved1[56];
>> +    } resp;
>> +};
>> +
>> +struct xencamera_evt {
>> +    uint16_t id;
>> +    uint8_t type;
>> +    uint8_t reserved[5];
>> +    union {
>> +        struct xencamera_frame_avail_evt frame_avail;
>> +        struct xencamera_ctrl_value ctrl_value;
>> +        uint8_t reserved[56];
>> +    } evt;
>> +};
>> +
>> +DEFINE_RING_TYPES(xen_cameraif, struct xencamera_req, struct xencamera_resp);
>> +
>> +/*
>> + ******************************************************************************
>> + *                        Back to front events delivery
>> + ******************************************************************************
>> + * In order to deliver asynchronous events from back to front a shared page is
>> + * allocated by front and its granted reference propagated to back via
>> + * XenStore entries (evt-ring-ref/evt-event-channel).
>> + * This page has a common header used by both front and back to synchronize
>> + * access and control event's ring buffer, while back being a producer of the
>> + * events and front being a consumer. The rest of the page after the header
>> + * is used for event packets.
>> + *
>> + * Upon reception of an event(s) front may confirm its reception
>> + * for either each event, group of events or none.
>> + */
>> +
>> +struct xencamera_event_page {
>> +    uint32_t in_cons;
>> +    uint32_t in_prod;
>> +    uint8_t reserved[56];
>> +};
>> +
>> +#define XENCAMERA_EVENT_PAGE_SIZE 4096
>> +#define XENCAMERA_IN_RING_OFFS (sizeof(struct xencamera_event_page))
>> +#define XENCAMERA_IN_RING_SIZE (XENCAMERA_EVENT_PAGE_SIZE - XENCAMERA_IN_RING_OFFS)
>> +#define XENCAMERA_IN_RING_LEN (XENCAMERA_IN_RING_SIZE / sizeof(struct xencamera_evt))
>> +#define XENCAMERA_IN_RING(page) \
>> +    ((struct xencamera_evt *)((char *)(page) + XENCAMERA_IN_RING_OFFS))
>> +#define XENCAMERA_IN_RING_REF(page, idx) \
>> +    (XENCAMERA_IN_RING((page))[(idx) % XENCAMERA_IN_RING_LEN])
>> +
>> +#endif /* __XEN_PUBLIC_IO_CAMERAIF_H__ */
>> +
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * tab-width: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>>
Jürgen Groß April 1, 2019, 6:35 a.m. UTC | #4
On 22/03/2019 08:37, Oleksandr Andrushchenko wrote:
> From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> 
> This is the ABI for the two halves of a para-virtualized
> camera driver which extends Xen's reach multimedia capabilities even
> farther enabling it for video conferencing, In-Vehicle Infotainment,
> high definition maps etc.
> 
> The initial goal is to support most needed functionality with the
> final idea to make it possible to extend the protocol if need be:
> 
> 1. Provide means for base virtual device configuration:
>  - pixel formats
>  - resolutions
>  - frame rates
> 2. Support basic camera controls:
>  - contrast
>  - brightness
>  - hue
>  - saturation
> 3. Support streaming control
> 
> Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen
Oleksandr Andrushchenko April 2, 2019, 5:37 a.m. UTC | #5
On 4/1/19 9:35 AM, Juergen Gross wrote:
> On 22/03/2019 08:37, Oleksandr Andrushchenko wrote:
>> From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
>>
>> This is the ABI for the two halves of a para-virtualized
>> camera driver which extends Xen's reach multimedia capabilities even
>> farther enabling it for video conferencing, In-Vehicle Infotainment,
>> high definition maps etc.
>>
>> The initial goal is to support most needed functionality with the
>> final idea to make it possible to extend the protocol if need be:
>>
>> 1. Provide means for base virtual device configuration:
>>   - pixel formats
>>   - resolutions
>>   - frame rates
>> 2. Support basic camera controls:
>>   - contrast
>>   - brightness
>>   - hue
>>   - saturation
>> 3. Support streaming control
>>
>> Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Reviewed-by: Juergen Gross <jgross@suse.com>
Thank you, is it good for inclusion in Xen?
>
> Juergen
>
Oleksandr Andrushchenko April 8, 2019, 6:16 a.m. UTC | #6
On 4/2/19 8:37 AM, Oleksandr Andrushchenko wrote:
> On 4/1/19 9:35 AM, Juergen Gross wrote:
>> On 22/03/2019 08:37, Oleksandr Andrushchenko wrote:
>>> From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
>>>
>>> This is the ABI for the two halves of a para-virtualized
>>> camera driver which extends Xen's reach multimedia capabilities even
>>> farther enabling it for video conferencing, In-Vehicle Infotainment,
>>> high definition maps etc.
>>>
>>> The initial goal is to support most needed functionality with the
>>> final idea to make it possible to extend the protocol if need be:
>>>
>>> 1. Provide means for base virtual device configuration:
>>>   - pixel formats
>>>   - resolutions
>>>   - frame rates
>>> 2. Support basic camera controls:
>>>   - contrast
>>>   - brightness
>>>   - hue
>>>   - saturation
>>> 3. Support streaming control
>>>
>>> Signed-off-by: Oleksandr Andrushchenko 
>>> <oleksandr_andrushchenko@epam.com>
>> Reviewed-by: Juergen Gross <jgross@suse.com>
> Thank you, is it good for inclusion in Xen?
ping
>>
>> Juergen
>>
>
diff mbox series

Patch

diff --git a/xen/include/public/io/cameraif.h b/xen/include/public/io/cameraif.h
new file mode 100644
index 000000000000..acbcbf3bd411
--- /dev/null
+++ b/xen/include/public/io/cameraif.h
@@ -0,0 +1,1374 @@ 
+/******************************************************************************
+ * cameraif.h
+ *
+ * Unified camera device I/O interface for Xen guest OSes.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Copyright (C) 2018-2019 EPAM Systems Inc.
+ *
+ * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
+ */
+
+#ifndef __XEN_PUBLIC_IO_CAMERAIF_H__
+#define __XEN_PUBLIC_IO_CAMERAIF_H__
+
+#include "ring.h"
+#include "../grant_table.h"
+
+/*
+ ******************************************************************************
+ *                           Protocol version
+ ******************************************************************************
+ */
+#define XENCAMERA_PROTOCOL_VERSION     "1"
+
+/*
+ ******************************************************************************
+ *                  Feature and Parameter Negotiation
+ ******************************************************************************
+ *
+ * Front->back notifications: when enqueuing a new request, sending a
+ * notification can be made conditional on xencamera_req (i.e., the generic
+ * hold-off mechanism provided by the ring macros). Backends must set
+ * xencamera_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()).
+ *
+ * Back->front notifications: when enqueuing a new response, sending a
+ * notification can be made conditional on xencamera_resp (i.e., the generic
+ * hold-off mechanism provided by the ring macros). Frontends must set
+ * xencamera_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
+ *
+ * The two halves of a para-virtual camera driver utilize nodes within
+ * XenStore to communicate capabilities and to negotiate operating parameters.
+ * This section enumerates these nodes which reside in the respective front and
+ * backend portions of XenStore, following the XenBus convention.
+ *
+ * All data in XenStore is stored as strings. Nodes specifying numeric
+ * values are encoded in decimal. Integer value ranges listed below are
+ * expressed as fixed sized integer types capable of storing the conversion
+ * of a properly formatted node string, without loss of information.
+ *
+ ******************************************************************************
+ *                        Example configuration
+ ******************************************************************************
+ *
+ * This is an example of backend and frontend configuration:
+ *
+ *--------------------------------- Backend -----------------------------------
+ *
+ * /local/domain/0/backend/vcamera/1/0/frontend-id = "1"
+ * /local/domain/0/backend/vcamera/1/0/frontend = "/local/domain/1/device/vcamera/0"
+ * /local/domain/0/backend/vcamera/1/0/state = "4"
+ * /local/domain/0/backend/vcamera/1/0/versions = "1,2"
+ *
+ *--------------------------------- Frontend ----------------------------------
+ *
+ * /local/domain/1/device/vcamera/0/backend-id = "0"
+ * /local/domain/1/device/vcamera/0/backend = "/local/domain/0/backend/vcamera/1"
+ * /local/domain/1/device/vcamera/0/state = "4"
+ * /local/domain/1/device/vcamera/0/version = "1"
+ * /local/domain/1/device/vcamera/0/be-alloc = "1"
+ *
+ *---------------------------- Device 0 configuration -------------------------
+ *
+ * /local/domain/1/device/vcamera/0/max-buffers = "3"
+ * /local/domain/1/device/vcamera/0/controls = "contrast,hue"
+ * /local/domain/1/device/vcamera/0/formats/YUYV/640x480/frame-rates = "30/1,15/1"
+ * /local/domain/1/device/vcamera/0/formats/YUYV/1920x1080/frame-rates = "15/2"
+ * /local/domain/1/device/vcamera/0/formats/BGRA/640x480/frame-rates = "15/1,15/2"
+ * /local/domain/1/device/vcamera/0/formats/BGRA/1200x720/frame-rates = "15/2"
+ * /local/domain/1/device/vcamera/0/unique-id = "0"
+ * /local/domain/1/device/vcamera/0/req-ring-ref = "2832"
+ * /local/domain/1/device/vcamera/0/req-event-channel = "15"
+ * /local/domain/1/device/vcamera/0/evt-ring-ref = "387"
+ * /local/domain/1/device/vcamera/0/evt-event-channel = "16"
+ *
+ *---------------------------- Device 1 configuration -------------------------
+ *
+ * /local/domain/1/device/vcamera/1/max-buffers = "8"
+ * /local/domain/1/device/vcamera/1/controls = "brightness,saturation,hue"
+ * /local/domain/1/device/vcamera/1/formats/YUYV/640x480/frame-rates = "30/1,15/2"
+ * /local/domain/1/device/vcamera/1/formats/YUYV/1920x1080/frame-rates = "15/2"
+ * /local/domain/1/device/vcamera/1/unique-id = "1"
+ * /local/domain/1/device/vcamera/1/req-ring-ref = "2833"
+ * /local/domain/1/device/vcamera/1/req-event-channel = "17"
+ * /local/domain/1/device/vcamera/1/evt-ring-ref = "388"
+ * /local/domain/1/device/vcamera/1/evt-event-channel = "18"
+ *
+ ******************************************************************************
+ *                            Backend XenBus Nodes
+ ******************************************************************************
+ *
+ *----------------------------- Protocol version ------------------------------
+ *
+ * versions
+ *      Values:         <string>
+ *
+ *      List of XENCAMERA_LIST_SEPARATOR separated protocol versions supported
+ *      by the backend. For example "1,2,3".
+ *
+ ******************************************************************************
+ *                            Frontend XenBus Nodes
+ ******************************************************************************
+ *
+ *-------------------------------- Addressing ---------------------------------
+ *
+ * dom-id
+ *      Values:         <uint16_t>
+ *
+ *      Domain identifier.
+ *
+ * dev-id
+ *      Values:         <uint16_t>
+ *
+ *      Device identifier.
+ *
+ *      /local/domain/<dom-id>/device/vcamera/<dev-id>/...
+ *
+ *----------------------------- Protocol version ------------------------------
+ *
+ * version
+ *      Values:         <string>
+ *
+ *      Protocol version, chosen among the ones supported by the backend.
+ *
+ *------------------------- Backend buffer allocation -------------------------
+ *
+ * be-alloc
+ *      Values:         "0", "1"
+ *
+ *      If value is set to "1", then backend will be the buffer
+ *      provider/allocator for this domain during XENCAMERA_OP_BUF_CREATE
+ *      operation.
+ *      If value is not "1" or omitted frontend must allocate buffers itself.
+ *
+ *------------------------------- Camera settings -----------------------------
+ *
+ * unique-id
+ *      Values:         <string>
+ *
+ *      After device instance initialization each camera is assigned a
+ *      unique ID, so it can be identified by the backend by this ID.
+ *      This can be UUID or such.
+ *
+ * max-buffers
+ *      Values:         <uint8_t>
+ *
+ *      Maximum number of camera buffers this frontend may use.
+ *
+ * controls
+ *      Values:         <list of string>
+ *
+ *      List of supported camera controls separated by XENCAMERA_LIST_SEPARATOR.
+ *      Camera controls are expressed as a list of string values w/o any
+ *      ordering requirement.
+ *
+ * formats
+ *      Values:         <format, char[7]>
+ *
+ *      Formats are organized as a set of directories one per each
+ *      supported pixel format. The name of the directory is the
+ *      corresponding FOURCC string label. The next level of
+ *      the directory under <formats> represents supported resolutions.
+ *      If the format represents a big-endian variant of a little
+ *      endian format, then the "-BE" suffix must be added. E.g. 'AR15' vs
+ *      'AR15-BE'.
+ *      If FOURCC string label has spaces then those are only allowed to
+ *      be at the end of the label and must be trimmed, for example
+ *      'Y16' and 'Y16-BE' will be trimmed.
+ *
+ * resolution
+ *      Values:         <width, uint32_t>x<height, uint32_t>
+ *
+ *      Resolutions are organized as a set of directories one per each
+ *      supported resolution under corresponding <formats> directory.
+ *      The name of the directory is the supported width and height
+ *      of the camera resolution in pixels.
+ *
+ * frame-rates
+ *      Values:         <numerator, uint32_t>/<denominator, uint32_t>
+ *
+ *      List of XENCAMERA_FRAME_RATE_SEPARATOR separated supported frame rates
+ *      of the camera expressed as numerator and denominator of the
+ *      corresponding frame rate.
+ *
+ *------------------- Camera Request Transport Parameters ---------------------
+ *
+ * This communication path is used to deliver requests from frontend to backend
+ * and get the corresponding responses from backend to frontend,
+ * set up per virtual camera device.
+ *
+ * req-event-channel
+ *      Values:         <uint32_t>
+ *
+ *      The identifier of the Xen camera's control event channel
+ *      used to signal activity in the ring buffer.
+ *
+ * req-ring-ref
+ *      Values:         <uint32_t>
+ *
+ *      The Xen grant reference granting permission for the backend to map
+ *      a sole page of camera's control ring buffer.
+ *
+ *-------------------- Camera Event Transport Parameters ----------------------
+ *
+ * This communication path is used to deliver asynchronous events from backend
+ * to frontend, set up per virtual camera device.
+ *
+ * evt-event-channel
+ *      Values:         <uint32_t>
+ *
+ *      The identifier of the Xen camera's event channel
+ *      used to signal activity in the ring buffer.
+ *
+ * evt-ring-ref
+ *      Values:         <uint32_t>
+ *
+ *      The Xen grant reference granting permission for the backend to map
+ *      a sole page of camera's event ring buffer.
+ */
+
+/*
+ ******************************************************************************
+ *                               STATE DIAGRAMS
+ ******************************************************************************
+ *
+ * Tool stack creates front and back state nodes with initial state
+ * XenbusStateInitialising.
+ * Tool stack creates and sets up frontend camera configuration
+ * nodes per domain.
+ *
+ *-------------------------------- Normal flow --------------------------------
+ *
+ * Front                                Back
+ * =================================    =====================================
+ * XenbusStateInitialising              XenbusStateInitialising
+ *                                       o Query backend device identification
+ *                                         data.
+ *                                       o Open and validate backend device.
+ *                                                |
+ *                                                |
+ *                                                V
+ *                                      XenbusStateInitWait
+ *
+ * o Query frontend configuration
+ * o Allocate and initialize
+ *   event channels per configured
+ *   camera.
+ * o Publish transport parameters
+ *   that will be in effect during
+ *   this connection.
+ *              |
+ *              |
+ *              V
+ * XenbusStateInitialised
+ *
+ *                                       o Query frontend transport parameters.
+ *                                       o Connect to the event channels.
+ *                                                |
+ *                                                |
+ *                                                V
+ *                                      XenbusStateConnected
+ *
+ *  o Create and initialize OS
+ *    virtual camera as per
+ *    configuration.
+ *              |
+ *              |
+ *              V
+ * XenbusStateConnected
+ *
+ *                                      XenbusStateUnknown
+ *                                      XenbusStateClosed
+ *                                      XenbusStateClosing
+ * o Remove virtual camera device
+ * o Remove event channels
+ *              |
+ *              |
+ *              V
+ * XenbusStateClosed
+ *
+ *------------------------------- Recovery flow -------------------------------
+ *
+ * In case of frontend unrecoverable errors backend handles that as
+ * if frontend goes into the XenbusStateClosed state.
+ *
+ * In case of backend unrecoverable errors frontend tries removing
+ * the virtualized device. If this is possible at the moment of error,
+ * then frontend goes into the XenbusStateInitialising state and is ready for
+ * new connection with backend. If the virtualized device is still in use and
+ * cannot be removed, then frontend goes into the XenbusStateReconfiguring state
+ * until either the virtualized device is removed or backend initiates a new
+ * connection. On the virtualized device removal frontend goes into the
+ * XenbusStateInitialising state.
+ *
+ * Note on XenbusStateReconfiguring state of the frontend: if backend has
+ * unrecoverable errors then frontend cannot send requests to the backend
+ * and thus cannot provide functionality of the virtualized device anymore.
+ * After backend is back to normal the virtualized device may still hold some
+ * state: configuration in use, allocated buffers, client application state etc.
+ * In most cases, this will require frontend to implement complex recovery
+ * reconnect logic. Instead, by going into XenbusStateReconfiguring state,
+ * frontend will make sure no new clients of the virtualized device are
+ * accepted, allow existing client(s) to exit gracefully by signaling error
+ * state etc.
+ * Once all the clients are gone frontend can reinitialize the virtualized
+ * device and get into XenbusStateInitialising state again signaling the
+ * backend that a new connection can be made.
+ *
+ * There are multiple conditions possible under which frontend will go from
+ * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS
+ * specific. For example:
+ * 1. The underlying OS framework may provide callbacks to signal that the last
+ *    client of the virtualized device has gone and the device can be removed
+ * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue)
+ *    to periodically check if this is the right time to re-try removal of
+ *    the virtualized device.
+ * 3. By any other means.
+ *
+ ******************************************************************************
+ *                             REQUEST CODES
+ ******************************************************************************
+ */
+#define XENCAMERA_OP_CONFIG_SET        0x00
+#define XENCAMERA_OP_CONFIG_GET        0x01
+#define XENCAMERA_OP_CONFIG_VALIDATE   0x02
+#define XENCAMERA_OP_FRAME_RATE_SET    0x03
+#define XENCAMERA_OP_BUF_GET_LAYOUT    0x04
+#define XENCAMERA_OP_BUF_REQUEST       0x05
+#define XENCAMERA_OP_BUF_CREATE        0x06
+#define XENCAMERA_OP_BUF_DESTROY       0x07
+#define XENCAMERA_OP_BUF_QUEUE         0x08
+#define XENCAMERA_OP_BUF_DEQUEUE       0x09
+#define XENCAMERA_OP_CTRL_ENUM         0x0a
+#define XENCAMERA_OP_CTRL_SET          0x0b
+#define XENCAMERA_OP_CTRL_GET          0x0c
+#define XENCAMERA_OP_STREAM_START      0x0d
+#define XENCAMERA_OP_STREAM_STOP       0x0e
+
+#define XENCAMERA_CTRL_BRIGHTNESS      0
+#define XENCAMERA_CTRL_CONTRAST        1
+#define XENCAMERA_CTRL_SATURATION      2
+#define XENCAMERA_CTRL_HUE             3
+
+/* Number of supported controls. */
+#define XENCAMERA_MAX_CTRL             4
+
+/* Control is read-only. */
+#define XENCAMERA_CTRL_FLG_RO          (1 << 0)
+/* Control is write-only. */
+#define XENCAMERA_CTRL_FLG_WO          (1 << 1)
+/* Control's value is volatile. */
+#define XENCAMERA_CTRL_FLG_VOLATILE    (1 << 2)
+
+/* Supported color spaces. */
+#define XENCAMERA_COLORSPACE_DEFAULT   0
+#define XENCAMERA_COLORSPACE_SMPTE170M 1
+#define XENCAMERA_COLORSPACE_REC709    2
+#define XENCAMERA_COLORSPACE_SRGB      3
+#define XENCAMERA_COLORSPACE_OPRGB     4
+#define XENCAMERA_COLORSPACE_BT2020    5
+#define XENCAMERA_COLORSPACE_DCI_P3    6
+
+/* Color space transfer function. */
+#define XENCAMERA_XFER_FUNC_DEFAULT    0
+#define XENCAMERA_XFER_FUNC_709        1
+#define XENCAMERA_XFER_FUNC_SRGB       2
+#define XENCAMERA_XFER_FUNC_OPRGB      3
+#define XENCAMERA_XFER_FUNC_NONE       4
+#define XENCAMERA_XFER_FUNC_DCI_P3     5
+#define XENCAMERA_XFER_FUNC_SMPTE2084  6
+
+/* Color space Y’CbCr encoding. */
+#define XENCAMERA_YCBCR_ENC_IGNORE           0
+#define XENCAMERA_YCBCR_ENC_601              1
+#define XENCAMERA_YCBCR_ENC_709              2
+#define XENCAMERA_YCBCR_ENC_XV601            3
+#define XENCAMERA_YCBCR_ENC_XV709            4
+#define XENCAMERA_YCBCR_ENC_BT2020           5
+#define XENCAMERA_YCBCR_ENC_BT2020_CONST_LUM 6
+
+/* Quantization range. */
+#define XENCAMERA_QUANTIZATION_DEFAULT       0
+#define XENCAMERA_QUANTIZATION_FULL_RANGE    1
+#define XENCAMERA_QUANTIZATION_LIM_RANGE     2
+
+/*
+ ******************************************************************************
+ *                                 EVENT CODES
+ ******************************************************************************
+ */
+#define XENCAMERA_EVT_FRAME_AVAIL      0x00
+#define XENCAMERA_EVT_CTRL_CHANGE      0x01
+
+/*
+ ******************************************************************************
+ *               XENSTORE FIELD AND PATH NAME STRINGS, HELPERS
+ ******************************************************************************
+ */
+#define XENCAMERA_DRIVER_NAME          "vcamera"
+
+#define XENCAMERA_LIST_SEPARATOR       ","
+#define XENCAMERA_RESOLUTION_SEPARATOR "x"
+#define XENCAMERA_FRACTION_SEPARATOR   "/"
+
+#define XENCAMERA_FIELD_BE_VERSIONS    "versions"
+#define XENCAMERA_FIELD_FE_VERSION     "version"
+#define XENCAMERA_FIELD_REQ_RING_REF   "req-ring-ref"
+#define XENCAMERA_FIELD_REQ_CHANNEL    "req-event-channel"
+#define XENCAMERA_FIELD_EVT_RING_REF   "evt-ring-ref"
+#define XENCAMERA_FIELD_EVT_CHANNEL    "evt-event-channel"
+#define XENCAMERA_FIELD_MAX_BUFFERS    "max-buffers"
+#define XENCAMERA_FIELD_CONTROLS       "controls"
+#define XENCAMERA_FIELD_FORMATS        "formats"
+#define XENCAMERA_FIELD_FRAME_RATES    "frame-rates"
+#define XENCAMERA_FIELD_BE_ALLOC       "be-alloc"
+#define XENCAMERA_FIELD_UNIQUE_ID      "unique-id"
+
+#define XENCAMERA_CTRL_BRIGHTNESS_STR  "brightness"
+#define XENCAMERA_CTRL_CONTRAST_STR    "contrast"
+#define XENCAMERA_CTRL_SATURATION_STR  "saturation"
+#define XENCAMERA_CTRL_HUE_STR         "hue"
+
+#define XENCAMERA_FOURCC_BIGENDIAN_STR "-BE"
+
+/* Maximum number of buffer planes supported. */
+#define XENCAMERA_MAX_PLANE            4
+
+/*
+ ******************************************************************************
+ *                          STATUS RETURN CODES
+ ******************************************************************************
+ *
+ * Status return code is zero on success and -XEN_EXX on failure.
+ *
+ ******************************************************************************
+ *                              Assumptions
+ ******************************************************************************
+ *
+ * - usage of grant reference 0 as invalid grant reference:
+ *   grant reference 0 is valid, but never exposed to a PV driver,
+ *   because of the fact it is already in use/reserved by the PV console.
+ * - all references in this document to page sizes must be treated
+ *   as pages of size XEN_PAGE_SIZE unless otherwise noted.
+ * - all FOURCC mappings used for configuration and messaging are
+ *   Linux V4L2 ones: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/videodev2.h
+ *   with the following exceptions:
+ *     - characters are allowed in [0x20; 0x7f] range
+ *     - when used for XenStore configuration entries the following
+ *       are not allowed:
+ *       - '/', '\', ' ' (space), '<', '>', ':', '"', '|', '?', '*'
+ *       - if trailing spaces are part of the FOURCC code then those must be
+ *         trimmed
+ *
+ *
+ ******************************************************************************
+ *       Description of the protocol between frontend and backend driver
+ ******************************************************************************
+ *
+ * The two halves of a Para-virtual camera driver communicate with
+ * each other using shared pages and event channels.
+ * Shared page contains a ring with request/response packets.
+ *
+ * All reserved fields in the structures below must be 0.
+ *
+ * For all request/response/event packets:
+ *   - frame rate parameter is represented as a pair of 4 octet long
+ *     numerator and denominator:
+ *       - frame_rate_numer - uint32_t, numerator of the frame rate
+ *       - frame_rate_denom - uint32_t, denominator of the frame rate
+ *     The corresponding frame rate (Hz) is calculated as:
+ *       frame_rate = frame_rate_numer / frame_rate_denom
+ *   - buffer index is a zero based index of the buffer. Must be less than
+ *     the value of XENCAMERA_OP_CONFIG_SET.num_bufs response:
+ *       - index - uint8_t, index of the buffer.
+ *
+ *
+ *---------------------------------- Requests ---------------------------------
+ *
+ * All request packets have the same length (64 octets).
+ * All request packets have common header:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |    operation   |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ *   id - uint16_t, private guest value, echoed in response.
+ *   operation - uint8_t, operation code, XENCAMERA_OP_XXX.
+ *
+ *
+ * Request to set/validate the configuration - request to set the
+ * configuration/mode of the camera (XENCAMERA_OP_CONFIG_SET) or to
+ * check if the configuration is valid and can be used
+ * (XENCAMERA_OP_CONFIG_VALIDATE):
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _OP_CONFIG_XXX |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                            pixel format                           | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                               width                               | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                               height                              | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 24
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * pixel_format - uint32_t, pixel format to be used, FOURCC code.
+ * width - uint32_t, width in pixels.
+ * height - uint32_t, height in pixels.
+ *
+ * See response format for this request.
+ *
+ * Notes:
+ *  - the only difference between XENCAMERA_OP_CONFIG_VALIDATE and
+ *    XENCAMERA_OP_CONFIG_SET is that the former doesn't actually change
+ *    camera configuration, but queries if the configuration is valid.
+ *    This can be used while stream is active and/or buffers allocated.
+ *  - frontend must check the corresponding response in order to see
+ *    if the values reported back by the backend do match the desired ones
+ *    and can be accepted.
+ *  - frontend may send multiple XENCAMERA_OP_CONFIG_SET requests before
+ *    sending XENCAMERA_OP_STREAM_START request to update or tune the
+ *    final stream configuration.
+ *  - configuration cannot be changed during active streaming, e.g.
+ *    after XENCAMERA_OP_STREAM_START and before XENCAMERA_OP_STREAM_STOP
+ *    requests.
+ */
+struct xencamera_config_req {
+    uint32_t pixel_format;
+    uint32_t width;
+    uint32_t height;
+};
+
+/*
+ * Request current configuration of the camera:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _OP_CONFIG_GET |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * See response format for this request.
+ *
+ *
+ * Request to set the frame rate of the stream:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _FRAME_RATE_SET|   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                          frame_rate_numer                         | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                          frame_rate_denom                         | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * frame_rate_numer - uint32_t, numerator of the frame rate.
+ * frame_rate_denom - uint32_t, denominator of the frame rate.
+ *
+ * Notes:
+ *  - to query the current (actual) frame rate use XENCAMERA_OP_CONFIG_GET
+ *    request.
+ *  - this request can be used with camera buffers allocated, but stream
+ *    stopped, e.g. frontend is allowed to stop the stream with
+ *    XENCAMERA_OP_STREAM_STOP, hold the buffers allocated (e.g. keep the
+ *    configuration set with XENCAMERA_OP_CONFIG_SET), change the
+ *    frame rate of the stream and (re)start the stream again with
+ *    XENCAMERA_OP_STREAM_START.
+ *  - frame rate cannot be changed during active streaming, e.g.
+ *    after XENCAMERA_OP_STREAM_START and before XENCAMERA_OP_STREAM_STOP
+ *    commands.
+ */
+struct xencamera_frame_rate_req {
+    uint32_t frame_rate_numer;
+    uint32_t frame_rate_denom;
+};
+
+/*
+ * Request camera buffer's layout:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _BUF_GET_LAYOUT|   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * See response format for this request.
+ *
+ *
+ * Request number of buffers to be used:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _OP_BUF_REQUEST|   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |    num_bufs    |                     reserved                     | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * num_bufs - uint8_t, desired number of buffers to be used.
+ *
+ * If num_bufs is not zero then the backend validates the requested number of
+ * buffers and responds with the number of buffers allowed for this frontend.
+ * Frontend is responsible for checking the corresponding response in order to
+ * see if the values reported back by the backend do match the desired ones
+ * and can be accepted.
+ * Frontend is allowed to send multiple XENCAMERA_OP_BUF_REQUEST requests
+ * before sending XENCAMERA_OP_STREAM_START request to update or tune the
+ * final configuration.
+ * Frontend is not allowed to change the camera configuration after this call
+ * with a non-zero value of num_bufs. If camera reconfiguration is required
+ * then this request must be sent with num_bufs set to zero and any created
+ * buffers must be destroyed first.
+ * Frontend is not allowed to change the number of buffers after the
+ * streaming has started.
+ *
+ * If num_bufs is 0 and streaming has not started yet, then the backend will
+ * free all previously allocated buffers (if any).
+ * Trying to call this if streaming is in progress will result in an error.
+ *
+ * If camera reconfiguration is required then the streaming must be stopped
+ * and this request must be sent with num_bufs set to zero and any
+ * created buffers must be destroyed.
+ *
+ * Please note, that the number of buffers in this request must not exceed
+ * the value configured in XenStore.max-buffers.
+ *
+ * See response format for this request.
+ */
+struct xencamera_buf_request {
+    uint8_t num_bufs;
+};
+
+/*
+ * Request camera buffer creation:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _OP_BUF_CREATE |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |      index     |                     reserved                     | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                           plane_offset[0]                         | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                           plane_offset[1]                         | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                           plane_offset[2]                         | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                           plane_offset[3]                         | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                           gref_directory                          | 32
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 36
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * An attempt to create multiple buffers with the same index is an error.
+ * index can be re-used after destroying the corresponding camera buffer.
+ *
+ * index - uint8_t, index of the buffer to be created in the range
+ *   from 0 to the num_bufs field returned in response for
+ *   XENCAMERA_OP_BUF_REQUEST request
+ * plane_offset - array of uint32_t, offset of the corresponding plane
+ *   in octets from the buffer start. Number of offsets returned is
+ *   equal to the value returned in XENCAMERA_OP_BUF_GET_LAYOUT.num_planes.
+ * gref_directory - grant_ref_t, a reference to the first shared page
+ *   describing shared buffer references. The size of the buffer is equal to
+ *   XENCAMERA_OP_BUF_GET_LAYOUT.size response. At least one page exists. If
+ *   shared buffer size exceeds what can be addressed by this single page,
+ *   then reference to the next shared page must be supplied (see
+ *   gref_dir_next_page below).
+ *
+ * If XENCAMERA_FIELD_BE_ALLOC configuration entry is set, then backend will
+ * allocate the buffer with the parameters provided in this request and page
+ * directory is handled as follows:
+ *   Frontend on request:
+ *     - allocates pages for the directory (gref_directory,
+ *       gref_dir_next_page(s)
+ *     - grants permissions for the pages of the directory to the backend
+ *     - sets gref_dir_next_page fields
+ *   Backend on response:
+ *     - grants permissions for the pages of the buffer allocated to
+ *       the frontend
+ *     - fills in page directory with grant references
+ *       (gref[] in struct xencamera_page_directory)
+ */
+struct xencamera_buf_create_req {
+    uint8_t index;
+    uint8_t reserved[3];
+    uint32_t plane_offset[XENCAMERA_MAX_PLANE];
+    grant_ref_t gref_directory;
+};
+
+/*
+ * Shared page for XENCAMERA_OP_BUF_CREATE buffer descriptor (gref_directory in
+ * the request) employs a list of pages, describing all pages of the shared
+ * data buffer:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |                        gref_dir_next_page                         | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                              gref[0]                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                              gref[i]                              | i*4+8
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             gref[N - 1]                           | N*4+8
+ * +----------------+----------------+----------------+----------------+
+ *
+ * gref_dir_next_page - grant_ref_t, reference to the next page describing
+ *   page directory. Must be 0 if there are no more pages in the list.
+ * gref[i] - grant_ref_t, reference to a shared page of the buffer
+ *   allocated at XENCAMERA_OP_BUF_CREATE.
+ *
+ * Number of grant_ref_t entries in the whole page directory is not
+ * passed, but instead can be calculated as:
+ *   num_grefs_total = (XENCAMERA_OP_BUF_REQUEST.size + XEN_PAGE_SIZE - 1) /
+ *       XEN_PAGE_SIZE
+ */
+struct xencamera_page_directory {
+    grant_ref_t gref_dir_next_page;
+    grant_ref_t gref[1]; /* Variable length */
+};
+
+/*
+ * Request buffer destruction - destroy a previously allocated camera buffer:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _OP_BUF_DESTROY|   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |      index     |                     reserved                     | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * index - uint8_t, index of the buffer to be destroyed.
+ *
+ *
+ * Request queueing of the buffer for backend use:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _OP_BUF_QUEUE  |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |      index     |                     reserved                     | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Notes:
+ *  - frontends must not access the buffer content after this request until
+ *    response to XENCAMERA_OP_BUF_DEQUEUE has been received.
+ *  - buffers must be queued to the backend before destroying them with
+ *    XENCAMERA_OP_BUF_DESTROY.
+ *
+ * index - uint8_t, index of the buffer to be queued.
+ *
+ *
+ * Request dequeueing of the buffer for frontend use:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |_OP_BUF_DEQUEUE |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |      index     |                     reserved                     | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Notes:
+ *  - frontend is allowed to access the buffer content after the corresponding
+ *    response to this request.
+ *
+ * index - uint8_t, index of the buffer to be queued.
+ *
+ *
+ * Request camera control details:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _OP_CTRL_ENUM  |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |      index     |                     reserved                     | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 12
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * See response format for this request.
+ *
+ * index - uint8_t, index of the control to be queried.
+ */
+struct xencamera_index {
+    uint8_t index;
+};
+
+/*
+ * Request camera control change:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |  _OP_SET_CTRL  |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |       type     |                     reserved                     | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                          value low 32-bit                         | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                          value high 32-bit                        | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 28
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
+ * value - int64_t, new value of the control.
+ */
+struct xencamera_ctrl_value {
+    uint8_t type;
+    uint8_t reserved[7];
+    int64_t value;
+};
+
+/*
+ * Request camera control state:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |  _OP_GET_CTRL  |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |       type     |                     reserved                     | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 12
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * See response format for this request.
+ *
+ * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
+ */
+struct xencamera_get_ctrl_req {
+    uint8_t type;
+};
+
+/*
+ * Request camera capture stream start:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |_OP_STREAM_START|   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ *
+ * Request camera capture stream stop:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |_OP_STREAM_STOP |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ *
+ *---------------------------------- Responses --------------------------------
+ *
+ * All response packets have the same length (64 octets).
+ *
+ * All response packets have common header:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |    operation   |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                              status                               | 8
+ * +----------------+----------------+----------------+----------------+
+ *
+ * id - uint16_t, copied from the request.
+ * operation - uint8_t, XENCAMERA_OP_* - copied from request.
+ * status - int32_t, response status, zero on success and -XEN_EXX on failure.
+ *
+ *
+ * Configuration response - response for XENCAMERA_OP_CONFIG_SET,
+ * XENCAMERA_OP_CONFIG_GET and XENCAMERA_OP_CONFIG_VALIDATE requests:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _OP_CONFIG_XXX |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                               status                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                            pixel format                           | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                               width                               | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                               height                              | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                             colorspace                            | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                             xfer_func                             | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                             ycbcr_enc                             | 32
+ * +----------------+----------------+----------------+----------------+
+ * |                            quantization                           | 36
+ * +----------------+----------------+----------------+----------------+
+ * |                       displ_asp_ratio_numer                       | 40
+ * +----------------+----------------+----------------+----------------+
+ * |                       displ_asp_ratio_denom                       | 44
+ * +----------------+----------------+----------------+----------------+
+ * |                          frame_rate_numer                         | 48
+ * +----------------+----------------+----------------+----------------+
+ * |                          frame_rate_denom                         | 52
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 56
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Meaning of the corresponding values in this response is the same as for
+ * XENCAMERA_OP_CONFIG_SET and XENCAMERA_OP_FRAME_RATE_SET requests.
+ *
+ * colorspace - uint32_t, this supplements pixel_format parameter,
+ *   one of the XENCAMERA_COLORSPACE_XXX.
+ * xfer_func - uint32_t, this supplements colorspace parameter,
+ *   one of the XENCAMERA_XFER_FUNC_XXX.
+ * ycbcr_enc - uint32_t, this supplements colorspace parameter,
+ *   one of the XENCAMERA_YCBCR_ENC_XXX. Please note, that ycbcr_enc is only
+ *   valid for YCbCr pixelformats and should be ignored otherwise.
+ * quantization - uint32_t, this supplements colorspace parameter,
+ *   one of the XENCAMERA_QUANTIZATION_XXX.
+ * displ_asp_ratio_numer - uint32_t, numerator of the display aspect ratio.
+ * displ_asp_ratio_denom - uint32_t, denominator of the display aspect ratio.
+ */
+struct xencamera_config_resp {
+    uint32_t pixel_format;
+    uint32_t width;
+    uint32_t height;
+    uint32_t colorspace;
+    uint32_t xfer_func;
+    uint32_t ycbcr_enc;
+    uint32_t quantization;
+    uint32_t displ_asp_ratio_numer;
+    uint32_t displ_asp_ratio_denom;
+    uint32_t frame_rate_numer;
+    uint32_t frame_rate_denom;
+};
+
+/*
+ * Request buffer response - response for XENCAMERA_OP_BUF_GET_LAYOUT
+ * request:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |_BUF_GET_LAYOUT |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                               status                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |   num_planes   |                     reserved                     | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                                size                               | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                           plane_size[0]                           | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                           plane_size[1]                           | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                           plane_size[2]                           | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                           plane_size[3]                           | 32
+ * +----------------+----------------+----------------+----------------+
+ * |                          plane_stride[0]                          | 36
+ * +----------------+----------------+----------------+----------------+
+ * |                          plane_stride[1]                          | 40
+ * +----------------+----------------+----------------+----------------+
+ * |                          plane_stride[2]                          | 44
+ * +----------------+----------------+----------------+----------------+
+ * |                          plane_stride[3]                          | 48
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * num_planes - uint8_t, number of planes of the buffer.
+ * size - uint32_t, overall size of the buffer including sizes of the
+ *   individual planes and padding if applicable.
+ * plane_size - array of uint32_t, size in octets of the corresponding plane
+ *   including padding.
+ * plane_stride - array of uint32_t, size in octets occupied by the
+ *   corresponding single image line including padding if applicable.
+ *
+ * Note! The sizes and strides in this response apply to all buffers created
+ * with XENCAMERA_OP_BUF_CREATE command, but individual buffers may have
+ * different plane offsets, see XENCAMERA_OP_BUF_REQUEST.plane_offset.
+ */
+struct xencamera_buf_get_layout_resp {
+    uint8_t num_planes;
+    uint8_t reserved[3];
+    uint32_t size;
+    uint32_t plane_size[XENCAMERA_MAX_PLANE];
+    uint32_t plane_stride[XENCAMERA_MAX_PLANE];
+};
+
+/*
+ * Request buffer response - response for XENCAMERA_OP_BUF_REQUEST
+ * request:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |_OP_BUF_REQUEST |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                               status                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |   num_buffers  |                     reserved                     | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * num_buffers - uint8_t, number of buffers to be used.
+ *
+ *
+ * Control enumerate response - response for XENCAMERA_OP_CTRL_ENUM:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _OP_CTRL_ENUM  |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                               status                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |     index      |      type      |            reserved             | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                               flags                               | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                          min low 32-bits                          | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                          min high 32-bits                         | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                          max low 32-bits                          | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                          max high 32-bits                         | 32
+ * +----------------+----------------+----------------+----------------+
+ * |                         step low 32-bits                          | 36
+ * +----------------+----------------+----------------+----------------+
+ * |                         step high 32-bits                         | 40
+ * +----------------+----------------+----------------+----------------+
+ * |                        def_val low 32-bits                        | 44
+ * +----------------+----------------+----------------+----------------+
+ * |                        def_val high 32-bits                       | 48
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 52
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * index - uint8_t, index of the camera control in response.
+ * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
+ * flags - uint32_t, flags of the control, one of the XENCAMERA_CTRL_FLG_XXX.
+ * min - int64_t, minimum value of the control.
+ * max - int64_t, maximum value of the control.
+ * step - int64_t, minimum size in which control value can be changed.
+ * def_val - int64_t, default value of the control.
+ */
+struct xencamera_ctrl_enum_resp {
+    uint8_t index;
+    uint8_t type;
+    uint8_t reserved[2];
+    uint32_t flags;
+    int64_t min;
+    int64_t max;
+    int64_t step;
+    int64_t def_val;
+};
+
+/*
+ * Get control response - response for XENCAMERA_OP_CTRL_GET:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _OP_CTRL_GET   |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                               status                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |       type     |                     reserved                     | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                          value low 32-bit                         | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                          value high 32-bit                        | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 32
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
+ * value - int64_t, new value of the control.
+ */
+
+/*
+ *----------------------------------- Events ----------------------------------
+ *
+ * Events are sent via a shared page allocated by the front and propagated by
+ *   evt-event-channel/evt-ring-ref XenStore entries.
+ *
+ * All event packets have the same length (64 octets).
+ * All event packets have common header:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |      type      |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ *
+ * id - uint16_t, event id, may be used by front.
+ * type - uint8_t, type of the event.
+ *
+ *
+ * Frame captured event - event from back to front when a new captured
+ * frame is available:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |_EVT_FRAME_AVAIL|   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |      index     |                     reserved                     | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                              used_sz                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                              seq_num                              | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 24
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * index - uint8_t, index of the buffer that contains new captured frame,
+ *   see XENCAMERA_OP_BUF_CREATE description on the range
+ * used_sz - uint32_t, number of octets this frame has. This can be less
+ * than the XENCAMERA_OP_BUF_REQUEST.size (response) for compressed formats.
+ * seq_num - uint32_t, sequential number of the frame. Must be
+ *   monotonically increasing. If skips are detected in seq_num then that
+ *   means that the frames in-between were dropped. Note however that not
+ *   all video capture hardware is capable of detecting dropped frames.
+ *   In that case there will be no skips in the sequence counter.
+ */
+struct xencamera_frame_avail_evt {
+    uint8_t index;
+    uint8_t reserved[3];
+    uint32_t used_sz;
+    uint32_t seq_num;
+};
+
+/*
+ * Control change event- event from back to front when camera control
+ * has changed:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |_EVT_CTRL_CHANGE|   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |       type     |                     reserved                     | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                          value low 32-bit                         | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                          value high 32-bit                        | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 28
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * type - uint8_t, type of the control, one of the XENCAMERA_CTRL_XXX.
+ * value - int64_t, new value of the control.
+ *
+ * Notes:
+ *  - this event is not sent for write-only controls
+ *  - this event is not sent to the originator of the control change
+ *  - this event is not sent when frontend first connects, e.g. initial
+ *    control state must be explicitly queried
+ */
+
+struct xencamera_req {
+    uint16_t id;
+    uint8_t operation;
+    uint8_t reserved[5];
+    union {
+        struct xencamera_config_req config;
+        struct xencamera_frame_rate_req frame_rate;
+        struct xencamera_buf_request buf_request;
+        struct xencamera_buf_create_req buf_create;
+        struct xencamera_index index;
+        struct xencamera_ctrl_value ctrl_value;
+        struct xencamera_get_ctrl_req get_ctrl;
+        uint8_t reserved[56];
+    } req;
+};
+
+struct xencamera_resp {
+    uint16_t id;
+    uint8_t operation;
+    uint8_t reserved;
+    int32_t status;
+    union {
+        struct xencamera_config_resp config;
+        struct xencamera_buf_get_layout_resp buf_layout;
+        struct xencamera_buf_request buf_request;
+        struct xencamera_ctrl_enum_resp ctrl_enum;
+        struct xencamera_ctrl_value ctrl_value;
+        uint8_t reserved1[56];
+    } resp;
+};
+
+struct xencamera_evt {
+    uint16_t id;
+    uint8_t type;
+    uint8_t reserved[5];
+    union {
+        struct xencamera_frame_avail_evt frame_avail;
+        struct xencamera_ctrl_value ctrl_value;
+        uint8_t reserved[56];
+    } evt;
+};
+
+DEFINE_RING_TYPES(xen_cameraif, struct xencamera_req, struct xencamera_resp);
+
+/*
+ ******************************************************************************
+ *                        Back to front events delivery
+ ******************************************************************************
+ * In order to deliver asynchronous events from back to front a shared page is
+ * allocated by front and its granted reference propagated to back via
+ * XenStore entries (evt-ring-ref/evt-event-channel).
+ * This page has a common header used by both front and back to synchronize
+ * access and control event's ring buffer, while back being a producer of the
+ * events and front being a consumer. The rest of the page after the header
+ * is used for event packets.
+ *
+ * Upon reception of an event(s) front may confirm its reception
+ * for either each event, group of events or none.
+ */
+
+struct xencamera_event_page {
+    uint32_t in_cons;
+    uint32_t in_prod;
+    uint8_t reserved[56];
+};
+
+#define XENCAMERA_EVENT_PAGE_SIZE 4096
+#define XENCAMERA_IN_RING_OFFS (sizeof(struct xencamera_event_page))
+#define XENCAMERA_IN_RING_SIZE (XENCAMERA_EVENT_PAGE_SIZE - XENCAMERA_IN_RING_OFFS)
+#define XENCAMERA_IN_RING_LEN (XENCAMERA_IN_RING_SIZE / sizeof(struct xencamera_evt))
+#define XENCAMERA_IN_RING(page) \
+    ((struct xencamera_evt *)((char *)(page) + XENCAMERA_IN_RING_OFFS))
+#define XENCAMERA_IN_RING_REF(page, idx) \
+    (XENCAMERA_IN_RING((page))[(idx) % XENCAMERA_IN_RING_LEN])
+
+#endif /* __XEN_PUBLIC_IO_CAMERAIF_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */