aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-05-04 11:37:09 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-05-04 11:37:09 -0700
commita96480723c287c502b02659f4b347aecaa651ea1 (patch)
tree7abee4eb6d0d0b43103dc4f48554736d2b642bc2 /include
parentMerge tag 'modules-for-v4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux (diff)
parentxen: Move xen_have_vector_callback definition to enlighten.c (diff)
downloadlinux-dev-a96480723c287c502b02659f4b347aecaa651ea1.tar.xz
linux-dev-a96480723c287c502b02659f4b347aecaa651ea1.zip
Merge tag 'for-linus-4.12b-rc0b-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen updates from Juergen Gross: "Xen fixes and featrues for 4.12. The main changes are: - enable building the kernel with Xen support but without enabling paravirtualized mode (Vitaly Kuznetsov) - add a new 9pfs xen frontend driver (Stefano Stabellini) - simplify Xen's cpuid handling by making use of cpu capabilities (Juergen Gross) - add/modify some headers for new Xen paravirtualized devices (Oleksandr Andrushchenko) - EFI reset_system support under Xen (Julien Grall) - and the usual cleanups and corrections" * tag 'for-linus-4.12b-rc0b-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: (57 commits) xen: Move xen_have_vector_callback definition to enlighten.c xen: Implement EFI reset_system callback arm/xen: Consolidate calls to shutdown hypercall in a single helper xen: Export xen_reboot xen/x86: Call xen_smp_intr_init_pv() on BSP xen: Revert commits da72ff5bfcb0 and 72a9b186292d xen/pvh: Do not fill kernel's e820 map in init_pvh_bootparams() xen/scsifront: use offset_in_page() macro xen/arm,arm64: rename __generic_dma_ops to xen_get_dma_ops xen/arm,arm64: fix xen_dma_ops after 815dd18 "Consolidate get_dma_ops..." xen/9pfs: select CONFIG_XEN_XENBUS_FRONTEND x86/cpu: remove hypervisor specific set_cpu_features vmware: set cpu capabilities during platform initialization x86/xen: use capabilities instead of fake cpuid values for xsave x86/xen: use capabilities instead of fake cpuid values for x2apic x86/xen: use capabilities instead of fake cpuid values for mwait x86/xen: use capabilities instead of fake cpuid values for acpi x86/xen: use capabilities instead of fake cpuid values for acc x86/xen: use capabilities instead of fake cpuid values for mtrr x86/xen: use capabilities instead of fake cpuid values for aperf ...
Diffstat (limited to 'include')
-rw-r--r--include/xen/arm/page-coherent.h26
-rw-r--r--include/xen/interface/io/9pfs.h36
-rw-r--r--include/xen/interface/io/displif.h854
-rw-r--r--include/xen/interface/io/kbdif.h458
-rw-r--r--include/xen/interface/io/ring.h143
-rw-r--r--include/xen/interface/io/sndif.h793
-rw-r--r--include/xen/xen-ops.h19
7 files changed, 2293 insertions, 36 deletions
diff --git a/include/xen/arm/page-coherent.h b/include/xen/arm/page-coherent.h
index 95ce6ac3a971..b1b4ecdf329a 100644
--- a/include/xen/arm/page-coherent.h
+++ b/include/xen/arm/page-coherent.h
@@ -2,8 +2,16 @@
#define _ASM_ARM_XEN_PAGE_COHERENT_H
#include <asm/page.h>
+#include <asm/dma-mapping.h>
#include <linux/dma-mapping.h>
+static inline const struct dma_map_ops *xen_get_dma_ops(struct device *dev)
+{
+ if (dev && dev->archdata.dev_dma_ops)
+ return dev->archdata.dev_dma_ops;
+ return get_arch_dma_ops(NULL);
+}
+
void __xen_dma_map_page(struct device *hwdev, struct page *page,
dma_addr_t dev_addr, unsigned long offset, size_t size,
enum dma_data_direction dir, unsigned long attrs);
@@ -19,13 +27,13 @@ void __xen_dma_sync_single_for_device(struct device *hwdev,
static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
{
- return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
+ return xen_get_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
}
static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
{
- __generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
+ xen_get_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
}
static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
@@ -49,7 +57,7 @@ static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
* specific function.
*/
if (local)
- __generic_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs);
+ xen_get_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs);
else
__xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
}
@@ -67,8 +75,8 @@ static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
* specific function.
*/
if (pfn_valid(pfn)) {
- if (__generic_dma_ops(hwdev)->unmap_page)
- __generic_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs);
+ if (xen_get_dma_ops(hwdev)->unmap_page)
+ xen_get_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs);
} else
__xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
}
@@ -78,8 +86,8 @@ static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
{
unsigned long pfn = PFN_DOWN(handle);
if (pfn_valid(pfn)) {
- if (__generic_dma_ops(hwdev)->sync_single_for_cpu)
- __generic_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir);
+ if (xen_get_dma_ops(hwdev)->sync_single_for_cpu)
+ xen_get_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir);
} else
__xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
}
@@ -89,8 +97,8 @@ static inline void xen_dma_sync_single_for_device(struct device *hwdev,
{
unsigned long pfn = PFN_DOWN(handle);
if (pfn_valid(pfn)) {
- if (__generic_dma_ops(hwdev)->sync_single_for_device)
- __generic_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir);
+ if (xen_get_dma_ops(hwdev)->sync_single_for_device)
+ xen_get_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir);
} else
__xen_dma_sync_single_for_device(hwdev, handle, size, dir);
}
diff --git a/include/xen/interface/io/9pfs.h b/include/xen/interface/io/9pfs.h
new file mode 100644
index 000000000000..5b6c19dae5e2
--- /dev/null
+++ b/include/xen/interface/io/9pfs.h
@@ -0,0 +1,36 @@
+/*
+ * 9pfs.h -- Xen 9PFS transport
+ *
+ * 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) 2017 Stefano Stabellini <stefano@aporeto.com>
+ */
+
+#ifndef __XEN_PUBLIC_IO_9PFS_H__
+#define __XEN_PUBLIC_IO_9PFS_H__
+
+#include "xen/interface/io/ring.h"
+
+/*
+ * See docs/misc/9pfs.markdown in xen.git for the full specification:
+ * https://xenbits.xen.org/docs/unstable/misc/9pfs.html
+ */
+DEFINE_XEN_FLEX_RING_AND_INTF(xen_9pfs);
+
+#endif
diff --git a/include/xen/interface/io/displif.h b/include/xen/interface/io/displif.h
new file mode 100644
index 000000000000..596578d9be3e
--- /dev/null
+++ b/include/xen/interface/io/displif.h
@@ -0,0 +1,854 @@
+/******************************************************************************
+ * displif.h
+ *
+ * Unified display 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) 2016-2017 EPAM Systems Inc.
+ *
+ * Authors: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
+ * Oleksandr Grytsov <oleksandr_grytsov@epam.com>
+ */
+
+#ifndef __XEN_PUBLIC_IO_DISPLIF_H__
+#define __XEN_PUBLIC_IO_DISPLIF_H__
+
+#include "ring.h"
+#include "../grant_table.h"
+
+/*
+ ******************************************************************************
+ * Protocol version
+ ******************************************************************************
+ */
+#define XENDISPL_PROTOCOL_VERSION "1"
+
+/*
+ ******************************************************************************
+ * Main features provided by the protocol
+ ******************************************************************************
+ * This protocol aims to provide a unified protocol which fits more
+ * sophisticated use-cases than a framebuffer device can handle. At the
+ * moment basic functionality is supported with the intention to be extended:
+ * o multiple dynamically allocated/destroyed framebuffers
+ * o buffers of arbitrary sizes
+ * o buffer allocation at either back or front end
+ * o better configuration options including multiple display support
+ *
+ * Note: existing fbif can be used together with displif running at the
+ * same time, e.g. on Linux one provides framebuffer and another DRM/KMS
+ *
+ * Note: display resolution (XenStore's "resolution" property) defines
+ * visible area of the virtual display. At the same time resolution of
+ * the display and frame buffers may differ: buffers can be smaller, equal
+ * or bigger than the visible area. This is to enable use-cases, where backend
+ * may do some post-processing of the display and frame buffers supplied,
+ * e.g. those buffers can be just a part of the final composition.
+ *
+ ******************************************************************************
+ * Direction of improvements
+ ******************************************************************************
+ * Future extensions to the existing protocol may include:
+ * o display/connector cloning
+ * o allocation of objects other than display buffers
+ * o plane/overlay support
+ * o scaling support
+ * o rotation support
+ *
+ ******************************************************************************
+ * Feature and Parameter Negotiation
+ ******************************************************************************
+ *
+ * Front->back notifications: when enqueuing a new request, sending a
+ * notification can be made conditional on xendispl_req (i.e., the generic
+ * hold-off mechanism provided by the ring macros). Backends must set
+ * xendispl_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 xendispl_resp (i.e., the generic
+ * hold-off mechanism provided by the ring macros). Frontends must set
+ * xendispl_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
+ *
+ * The two halves of a para-virtual display 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 formated node string, without loss of information.
+ *
+ ******************************************************************************
+ * Example configuration
+ ******************************************************************************
+ *
+ * Note: depending on the use-case backend can expose more display connectors
+ * than the underlying HW physically has by employing SW graphics compositors
+ *
+ * This is an example of backend and frontend configuration:
+ *
+ *--------------------------------- Backend -----------------------------------
+ *
+ * /local/domain/0/backend/vdispl/1/0/frontend-id = "1"
+ * /local/domain/0/backend/vdispl/1/0/frontend = "/local/domain/1/device/vdispl/0"
+ * /local/domain/0/backend/vdispl/1/0/state = "4"
+ * /local/domain/0/backend/vdispl/1/0/versions = "1,2"
+ *
+ *--------------------------------- Frontend ----------------------------------
+ *
+ * /local/domain/1/device/vdispl/0/backend-id = "0"
+ * /local/domain/1/device/vdispl/0/backend = "/local/domain/0/backend/vdispl/1/0"
+ * /local/domain/1/device/vdispl/0/state = "4"
+ * /local/domain/1/device/vdispl/0/version = "1"
+ * /local/domain/1/device/vdispl/0/be-alloc = "1"
+ *
+ *-------------------------- Connector 0 configuration ------------------------
+ *
+ * /local/domain/1/device/vdispl/0/0/resolution = "1920x1080"
+ * /local/domain/1/device/vdispl/0/0/req-ring-ref = "2832"
+ * /local/domain/1/device/vdispl/0/0/req-event-channel = "15"
+ * /local/domain/1/device/vdispl/0/0/evt-ring-ref = "387"
+ * /local/domain/1/device/vdispl/0/0/evt-event-channel = "16"
+ *
+ *-------------------------- Connector 1 configuration ------------------------
+ *
+ * /local/domain/1/device/vdispl/0/1/resolution = "800x600"
+ * /local/domain/1/device/vdispl/0/1/req-ring-ref = "2833"
+ * /local/domain/1/device/vdispl/0/1/req-event-channel = "17"
+ * /local/domain/1/device/vdispl/0/1/evt-ring-ref = "388"
+ * /local/domain/1/device/vdispl/0/1/evt-event-channel = "18"
+ *
+ ******************************************************************************
+ * Backend XenBus Nodes
+ ******************************************************************************
+ *
+ *----------------------------- Protocol version ------------------------------
+ *
+ * versions
+ * Values: <string>
+ *
+ * List of XENDISPL_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.
+ *
+ * conn-idx
+ * Values: <uint8_t>
+ *
+ * Zero based contigous index of the connector.
+ * /local/domain/<dom-id>/device/vdispl/<dev-id>/<conn-idx>/...
+ *
+ *----------------------------- 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 can be a buffer provider/allocator
+ * for this domain during XENDISPL_OP_DBUF_CREATE operation (see below
+ * for negotiation).
+ * If value is not "1" or omitted frontend must allocate buffers itself.
+ *
+ *----------------------------- Connector settings ----------------------------
+ *
+ * resolution
+ * Values: <width, uint32_t>x<height, uint32_t>
+ *
+ * Width and height of the connector in pixels separated by
+ * XENDISPL_RESOLUTION_SEPARATOR. This defines visible area of the
+ * display.
+ *
+ *------------------ Connector 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 connector.
+ *
+ * req-event-channel
+ * Values: <uint32_t>
+ *
+ * The identifier of the Xen connector'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 connector's control ring buffer.
+ *
+ *------------------- Connector Event Transport Parameters --------------------
+ *
+ * This communication path is used to deliver asynchronous events from backend
+ * to frontend, set up per connector.
+ *
+ * evt-event-channel
+ * Values: <uint32_t>
+ *
+ * The identifier of the Xen connector'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 connector'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 display 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
+ * connector.
+ * 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 display connectors
+ * as per configuration.
+ * |
+ * |
+ * V
+ * XenbusStateConnected
+ *
+ * XenbusStateUnknown
+ * XenbusStateClosed
+ * XenbusStateClosing
+ * o Remove virtual display 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
+ ******************************************************************************
+ * Request codes [0; 15] are reserved and must not be used
+ */
+
+#define XENDISPL_OP_DBUF_CREATE 0x10
+#define XENDISPL_OP_DBUF_DESTROY 0x11
+#define XENDISPL_OP_FB_ATTACH 0x12
+#define XENDISPL_OP_FB_DETACH 0x13
+#define XENDISPL_OP_SET_CONFIG 0x14
+#define XENDISPL_OP_PG_FLIP 0x15
+
+/*
+ ******************************************************************************
+ * EVENT CODES
+ ******************************************************************************
+ */
+#define XENDISPL_EVT_PG_FLIP 0x00
+
+/*
+ ******************************************************************************
+ * XENSTORE FIELD AND PATH NAME STRINGS, HELPERS
+ ******************************************************************************
+ */
+#define XENDISPL_DRIVER_NAME "vdispl"
+
+#define XENDISPL_LIST_SEPARATOR ","
+#define XENDISPL_RESOLUTION_SEPARATOR "x"
+
+#define XENDISPL_FIELD_BE_VERSIONS "versions"
+#define XENDISPL_FIELD_FE_VERSION "version"
+#define XENDISPL_FIELD_REQ_RING_REF "req-ring-ref"
+#define XENDISPL_FIELD_REQ_CHANNEL "req-event-channel"
+#define XENDISPL_FIELD_EVT_RING_REF "evt-ring-ref"
+#define XENDISPL_FIELD_EVT_CHANNEL "evt-event-channel"
+#define XENDISPL_FIELD_RESOLUTION "resolution"
+#define XENDISPL_FIELD_BE_ALLOC "be-alloc"
+
+/*
+ ******************************************************************************
+ * STATUS RETURN CODES
+ ******************************************************************************
+ *
+ * Status return code is zero on success and -XEN_EXX on failure.
+ *
+ ******************************************************************************
+ * Assumptions
+ ******************************************************************************
+ * o 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.
+ * o all references in this document to page sizes must be treated
+ * as pages of size XEN_PAGE_SIZE unless otherwise noted.
+ *
+ ******************************************************************************
+ * Description of the protocol between frontend and backend driver
+ ******************************************************************************
+ *
+ * The two halves of a Para-virtual display 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.
+ * Display buffers's cookie of value 0 is treated as invalid.
+ * Framebuffer's cookie of value 0 is treated as invalid.
+ *
+ * For all request/response/event packets that use cookies:
+ * dbuf_cookie - uint64_t, unique to guest domain value used by the backend
+ * to map remote display buffer to its local one
+ * fb_cookie - uint64_t, unique to guest domain value used by the backend
+ * to map remote framebuffer to its local one
+ *
+ *---------------------------------- Requests ---------------------------------
+ *
+ * All requests/responses, which are not connector specific, must be sent over
+ * control ring of the connector which has the index value of 0:
+ * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref
+ *
+ * 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, XENDISPL_OP_???
+ *
+ * Request dbuf creation - request creation of a display buffer.
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id |_OP_DBUF_CREATE | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | dbuf_cookie low 32-bit | 12
+ * +----------------+----------------+----------------+----------------+
+ * | dbuf_cookie high 32-bit | 16
+ * +----------------+----------------+----------------+----------------+
+ * | width | 20
+ * +----------------+----------------+----------------+----------------+
+ * | height | 24
+ * +----------------+----------------+----------------+----------------+
+ * | bpp | 28
+ * +----------------+----------------+----------------+----------------+
+ * | buffer_sz | 32
+ * +----------------+----------------+----------------+----------------+
+ * | flags | 36
+ * +----------------+----------------+----------------+----------------+
+ * | gref_directory | 40
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 44
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Must be sent over control ring of the connector which has the index
+ * value of 0:
+ * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref
+ * All unused bits in flags field must be set to 0.
+ *
+ * An attempt to create multiple display buffers with the same dbuf_cookie is
+ * an error. dbuf_cookie can be re-used after destroying the corresponding
+ * display buffer.
+ *
+ * Width and height of the display buffers can be smaller, equal or bigger
+ * than the connector's resolution. Depth/pixel format of the individual
+ * buffers can differ as well.
+ *
+ * width - uint32_t, width in pixels
+ * height - uint32_t, height in pixels
+ * bpp - uint32_t, bits per pixel
+ * buffer_sz - uint32_t, buffer size to be allocated, octets
+ * flags - uint32_t, flags of the operation
+ * o XENDISPL_DBUF_FLG_REQ_ALLOC - if set, then backend is requested
+ * to allocate the buffer with the parameters provided in this request.
+ * Page directory is handled as follows:
+ * Frontend on request:
+ * o allocates pages for the directory (gref_directory,
+ * gref_dir_next_page(s)
+ * o grants permissions for the pages of the directory to the backend
+ * o sets gref_dir_next_page fields
+ * Backend on response:
+ * o grants permissions for the pages of the buffer allocated to
+ * the frontend
+ * o fills in page directory with grant references
+ * (gref[] in struct xendispl_page_directory)
+ * gref_directory - grant_ref_t, a reference to the first shared page
+ * describing shared buffer references. At least one page exists. If shared
+ * buffer size (buffer_sz) exceeds what can be addressed by this single page,
+ * then reference to the next page must be supplied (see gref_dir_next_page
+ * below)
+ */
+
+#define XENDISPL_DBUF_FLG_REQ_ALLOC (1 << 0)
+
+struct xendispl_dbuf_create_req {
+ uint64_t dbuf_cookie;
+ uint32_t width;
+ uint32_t height;
+ uint32_t bpp;
+ uint32_t buffer_sz;
+ uint32_t flags;
+ grant_ref_t gref_directory;
+};
+
+/*
+ * Shared page for XENDISPL_OP_DBUF_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 XENDISPL_OP_DBUF_CREATE
+ *
+ * Number of grant_ref_t entries in the whole page directory is not
+ * passed, but instead can be calculated as:
+ * num_grefs_total = (XENDISPL_OP_DBUF_CREATE.buffer_sz + XEN_PAGE_SIZE - 1) /
+ * XEN_PAGE_SIZE
+ */
+
+struct xendispl_page_directory {
+ grant_ref_t gref_dir_next_page;
+ grant_ref_t gref[1]; /* Variable length */
+};
+
+/*
+ * Request dbuf destruction - destroy a previously allocated display buffer:
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id |_OP_DBUF_DESTROY| reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | dbuf_cookie low 32-bit | 12
+ * +----------------+----------------+----------------+----------------+
+ * | dbuf_cookie high 32-bit | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Must be sent over control ring of the connector which has the index
+ * value of 0:
+ * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref
+ */
+
+struct xendispl_dbuf_destroy_req {
+ uint64_t dbuf_cookie;
+};
+
+/*
+ * Request framebuffer attachment - request attachment of a framebuffer to
+ * previously created display buffer.
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id | _OP_FB_ATTACH | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | dbuf_cookie low 32-bit | 12
+ * +----------------+----------------+----------------+----------------+
+ * | dbuf_cookie high 32-bit | 16
+ * +----------------+----------------+----------------+----------------+
+ * | fb_cookie low 32-bit | 20
+ * +----------------+----------------+----------------+----------------+
+ * | fb_cookie high 32-bit | 24
+ * +----------------+----------------+----------------+----------------+
+ * | width | 28
+ * +----------------+----------------+----------------+----------------+
+ * | height | 32
+ * +----------------+----------------+----------------+----------------+
+ * | pixel_format | 36
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Must be sent over control ring of the connector which has the index
+ * value of 0:
+ * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref
+ * Width and height can be smaller, equal or bigger than the connector's
+ * resolution.
+ *
+ * An attempt to create multiple frame buffers with the same fb_cookie is
+ * an error. fb_cookie can be re-used after destroying the corresponding
+ * frame buffer.
+ *
+ * width - uint32_t, width in pixels
+ * height - uint32_t, height in pixels
+ * pixel_format - uint32_t, pixel format of the framebuffer, FOURCC code
+ */
+
+struct xendispl_fb_attach_req {
+ uint64_t dbuf_cookie;
+ uint64_t fb_cookie;
+ uint32_t width;
+ uint32_t height;
+ uint32_t pixel_format;
+};
+
+/*
+ * Request framebuffer detach - detach a previously
+ * attached framebuffer from the display buffer in request:
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id | _OP_FB_DETACH | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | fb_cookie low 32-bit | 12
+ * +----------------+----------------+----------------+----------------+
+ * | fb_cookie high 32-bit | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Must be sent over control ring of the connector which has the index
+ * value of 0:
+ * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref
+ */
+
+struct xendispl_fb_detach_req {
+ uint64_t fb_cookie;
+};
+
+/*
+ * Request configuration set/reset - request to set or reset
+ * the configuration/mode of the display:
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id | _OP_SET_CONFIG | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | fb_cookie low 32-bit | 12
+ * +----------------+----------------+----------------+----------------+
+ * | fb_cookie high 32-bit | 16
+ * +----------------+----------------+----------------+----------------+
+ * | x | 20
+ * +----------------+----------------+----------------+----------------+
+ * | y | 24
+ * +----------------+----------------+----------------+----------------+
+ * | width | 28
+ * +----------------+----------------+----------------+----------------+
+ * | height | 32
+ * +----------------+----------------+----------------+----------------+
+ * | bpp | 40
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 44
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Pass all zeros to reset, otherwise command is treated as
+ * configuration set.
+ * Framebuffer's cookie defines which framebuffer/dbuf must be
+ * displayed while enabling display (applying configuration).
+ * x, y, width and height are bound by the connector's resolution and must not
+ * exceed it.
+ *
+ * x - uint32_t, starting position in pixels by X axis
+ * y - uint32_t, starting position in pixels by Y axis
+ * width - uint32_t, width in pixels
+ * height - uint32_t, height in pixels
+ * bpp - uint32_t, bits per pixel
+ */
+
+struct xendispl_set_config_req {
+ uint64_t fb_cookie;
+ uint32_t x;
+ uint32_t y;
+ uint32_t width;
+ uint32_t height;
+ uint32_t bpp;
+};
+
+/*
+ * Request page flip - request to flip a page identified by the framebuffer
+ * cookie:
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id | _OP_PG_FLIP | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | fb_cookie low 32-bit | 12
+ * +----------------+----------------+----------------+----------------+
+ * | fb_cookie high 32-bit | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 64
+ * +----------------+----------------+----------------+----------------+
+ */
+
+struct xendispl_page_flip_req {
+ uint64_t fb_cookie;
+};
+
+/*
+ *---------------------------------- Responses --------------------------------
+ *
+ * All response packets have the same length (64 octets)
+ *
+ * All response packets have common header:
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | status | 8
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 12
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * id - uint16_t, private guest value, echoed from request
+ * status - int32_t, response status, zero on success and -XEN_EXX on failure
+ *
+ *----------------------------------- 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
+ *
+ *
+ * Page flip complete event - event from back to front on page flip completed:
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id | _EVT_PG_FLIP | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | fb_cookie low 32-bit | 12
+ * +----------------+----------------+----------------+----------------+
+ * | fb_cookie high 32-bit | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 64
+ * +----------------+----------------+----------------+----------------+
+ */
+
+struct xendispl_pg_flip_evt {
+ uint64_t fb_cookie;
+};
+
+struct xendispl_req {
+ uint16_t id;
+ uint8_t operation;
+ uint8_t reserved[5];
+ union {
+ struct xendispl_dbuf_create_req dbuf_create;
+ struct xendispl_dbuf_destroy_req dbuf_destroy;
+ struct xendispl_fb_attach_req fb_attach;
+ struct xendispl_fb_detach_req fb_detach;
+ struct xendispl_set_config_req set_config;
+ struct xendispl_page_flip_req pg_flip;
+ uint8_t reserved[56];
+ } op;
+};
+
+struct xendispl_resp {
+ uint16_t id;
+ uint8_t operation;
+ uint8_t reserved;
+ int32_t status;
+ uint8_t reserved1[56];
+};
+
+struct xendispl_evt {
+ uint16_t id;
+ uint8_t type;
+ uint8_t reserved[5];
+ union {
+ struct xendispl_pg_flip_evt pg_flip;
+ uint8_t reserved[56];
+ } op;
+};
+
+DEFINE_RING_TYPES(xen_displif, struct xendispl_req, struct xendispl_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 xendispl_event_page {
+ uint32_t in_cons;
+ uint32_t in_prod;
+ uint8_t reserved[56];
+};
+
+#define XENDISPL_EVENT_PAGE_SIZE XEN_PAGE_SIZE
+#define XENDISPL_IN_RING_OFFS (sizeof(struct xendispl_event_page))
+#define XENDISPL_IN_RING_SIZE (XENDISPL_EVENT_PAGE_SIZE - XENDISPL_IN_RING_OFFS)
+#define XENDISPL_IN_RING_LEN (XENDISPL_IN_RING_SIZE / sizeof(struct xendispl_evt))
+#define XENDISPL_IN_RING(page) \
+ ((struct xendispl_evt *)((char *)(page) + XENDISPL_IN_RING_OFFS))
+#define XENDISPL_IN_RING_REF(page, idx) \
+ (XENDISPL_IN_RING((page))[(idx) % XENDISPL_IN_RING_LEN])
+
+#endif /* __XEN_PUBLIC_IO_DISPLIF_H__ */
diff --git a/include/xen/interface/io/kbdif.h b/include/xen/interface/io/kbdif.h
index 8066c7849fbe..2a9510ade701 100644
--- a/include/xen/interface/io/kbdif.h
+++ b/include/xen/interface/io/kbdif.h
@@ -26,43 +26,432 @@
#ifndef __XEN_PUBLIC_IO_KBDIF_H__
#define __XEN_PUBLIC_IO_KBDIF_H__
-/* In events (backend -> frontend) */
+/*
+ *****************************************************************************
+ * Feature and Parameter Negotiation
+ *****************************************************************************
+ *
+ * The two halves of a para-virtual 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 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 formated node string, without loss of information.
+ *
+ *****************************************************************************
+ * Backend XenBus Nodes
+ *****************************************************************************
+ *
+ *---------------------------- Features supported ----------------------------
+ *
+ * Capable backend advertises supported features by publishing
+ * corresponding entries in XenStore and puts 1 as the value of the entry.
+ * If a feature is not supported then 0 must be set or feature entry omitted.
+ *
+ * feature-abs-pointer
+ * Values: <uint>
+ *
+ * Backends, which support reporting of absolute coordinates for pointer
+ * device should set this to 1.
+ *
+ * feature-multi-touch
+ * Values: <uint>
+ *
+ * Backends, which support reporting of multi-touch events
+ * should set this to 1.
+ *
+ *------------------------- Pointer Device Parameters ------------------------
+ *
+ * width
+ * Values: <uint>
+ *
+ * Maximum X coordinate (width) to be used by the frontend
+ * while reporting input events, pixels, [0; UINT32_MAX].
+ *
+ * height
+ * Values: <uint>
+ *
+ * Maximum Y coordinate (height) to be used by the frontend
+ * while reporting input events, pixels, [0; UINT32_MAX].
+ *
+ *****************************************************************************
+ * Frontend XenBus Nodes
+ *****************************************************************************
+ *
+ *------------------------------ Feature request -----------------------------
+ *
+ * Capable frontend requests features from backend via setting corresponding
+ * entries to 1 in XenStore. Requests for features not advertised as supported
+ * by the backend have no effect.
+ *
+ * request-abs-pointer
+ * Values: <uint>
+ *
+ * Request backend to report absolute pointer coordinates
+ * (XENKBD_TYPE_POS) instead of relative ones (XENKBD_TYPE_MOTION).
+ *
+ * request-multi-touch
+ * Values: <uint>
+ *
+ * Request backend to report multi-touch events.
+ *
+ *----------------------- Request Transport Parameters -----------------------
+ *
+ * event-channel
+ * Values: <uint>
+ *
+ * The identifier of the Xen event channel used to signal activity
+ * in the ring buffer.
+ *
+ * page-gref
+ * Values: <uint>
+ *
+ * The Xen grant reference granting permission for the backend to map
+ * a sole page in a single page sized event ring buffer.
+ *
+ * page-ref
+ * Values: <uint>
+ *
+ * OBSOLETE, not recommended for use.
+ * PFN of the shared page.
+ *
+ *----------------------- Multi-touch Device Parameters -----------------------
+ *
+ * multi-touch-num-contacts
+ * Values: <uint>
+ *
+ * Number of simultaneous touches reported.
+ *
+ * multi-touch-width
+ * Values: <uint>
+ *
+ * Width of the touch area to be used by the frontend
+ * while reporting input events, pixels, [0; UINT32_MAX].
+ *
+ * multi-touch-height
+ * Values: <uint>
+ *
+ * Height of the touch area to be used by the frontend
+ * while reporting input events, pixels, [0; UINT32_MAX].
+ */
/*
- * Frontends should ignore unknown in events.
+ * EVENT CODES.
*/
-/* Pointer movement event */
-#define XENKBD_TYPE_MOTION 1
-/* Event type 2 currently not used */
-/* Key event (includes pointer buttons) */
-#define XENKBD_TYPE_KEY 3
+#define XENKBD_TYPE_MOTION 1
+#define XENKBD_TYPE_RESERVED 2
+#define XENKBD_TYPE_KEY 3
+#define XENKBD_TYPE_POS 4
+#define XENKBD_TYPE_MTOUCH 5
+
+/* Multi-touch event sub-codes */
+
+#define XENKBD_MT_EV_DOWN 0
+#define XENKBD_MT_EV_UP 1
+#define XENKBD_MT_EV_MOTION 2
+#define XENKBD_MT_EV_SYN 3
+#define XENKBD_MT_EV_SHAPE 4
+#define XENKBD_MT_EV_ORIENT 5
+
+/*
+ * CONSTANTS, XENSTORE FIELD AND PATH NAME STRINGS, HELPERS.
+ */
+
+#define XENKBD_DRIVER_NAME "vkbd"
+
+#define XENKBD_FIELD_FEAT_ABS_POINTER "feature-abs-pointer"
+#define XENKBD_FIELD_FEAT_MTOUCH "feature-multi-touch"
+#define XENKBD_FIELD_REQ_ABS_POINTER "request-abs-pointer"
+#define XENKBD_FIELD_REQ_MTOUCH "request-multi-touch"
+#define XENKBD_FIELD_RING_GREF "page-gref"
+#define XENKBD_FIELD_EVT_CHANNEL "event-channel"
+#define XENKBD_FIELD_WIDTH "width"
+#define XENKBD_FIELD_HEIGHT "height"
+#define XENKBD_FIELD_MT_WIDTH "multi-touch-width"
+#define XENKBD_FIELD_MT_HEIGHT "multi-touch-height"
+#define XENKBD_FIELD_MT_NUM_CONTACTS "multi-touch-num-contacts"
+
+/* OBSOLETE, not recommended for use */
+#define XENKBD_FIELD_RING_REF "page-ref"
+
/*
- * Pointer position event
- * Capable backend sets feature-abs-pointer in xenstore.
- * Frontend requests ot instead of XENKBD_TYPE_MOTION by setting
- * request-abs-update in xenstore.
+ *****************************************************************************
+ * Description of the protocol between frontend and backend driver.
+ *****************************************************************************
+ *
+ * The two halves of a Para-virtual driver communicate with
+ * each other using a shared page and an event channel.
+ * Shared page contains a ring with event structures.
+ *
+ * All reserved fields in the structures below must be 0.
+ *
+ *****************************************************************************
+ * Backend to frontend events
+ *****************************************************************************
+ *
+ * Frontends should ignore unknown in events.
+ * All event packets have the same length (40 octets)
+ * All event packets have common header:
+ *
+ * 0 octet
+ * +-----------------+
+ * | type |
+ * +-----------------+
+ * type - uint8_t, event code, XENKBD_TYPE_???
+ *
+ *
+ * Pointer relative movement event
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MOTION | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | rel_x | 8
+ * +----------------+----------------+----------------+----------------+
+ * | rel_y | 12
+ * +----------------+----------------+----------------+----------------+
+ * | rel_z | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * rel_x - int32_t, relative X motion
+ * rel_y - int32_t, relative Y motion
+ * rel_z - int32_t, relative Z motion (wheel)
*/
-#define XENKBD_TYPE_POS 4
struct xenkbd_motion {
- uint8_t type; /* XENKBD_TYPE_MOTION */
- int32_t rel_x; /* relative X motion */
- int32_t rel_y; /* relative Y motion */
- int32_t rel_z; /* relative Z motion (wheel) */
+ uint8_t type;
+ int32_t rel_x;
+ int32_t rel_y;
+ int32_t rel_z;
};
+/*
+ * Key event (includes pointer buttons)
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_KEY | pressed | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | keycode | 8
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 12
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * pressed - uint8_t, 1 if pressed; 0 otherwise
+ * keycode - uint32_t, KEY_* from linux/input.h
+ */
+
struct xenkbd_key {
- uint8_t type; /* XENKBD_TYPE_KEY */
- uint8_t pressed; /* 1 if pressed; 0 otherwise */
- uint32_t keycode; /* KEY_* from linux/input.h */
+ uint8_t type;
+ uint8_t pressed;
+ uint32_t keycode;
};
+/*
+ * Pointer absolute position event
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_POS | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | abs_x | 8
+ * +----------------+----------------+----------------+----------------+
+ * | abs_y | 12
+ * +----------------+----------------+----------------+----------------+
+ * | rel_z | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * abs_x - int32_t, absolute X position (in FB pixels)
+ * abs_y - int32_t, absolute Y position (in FB pixels)
+ * rel_z - int32_t, relative Z motion (wheel)
+ */
+
struct xenkbd_position {
- uint8_t type; /* XENKBD_TYPE_POS */
- int32_t abs_x; /* absolute X position (in FB pixels) */
- int32_t abs_y; /* absolute Y position (in FB pixels) */
- int32_t rel_z; /* relative Z motion (wheel) */
+ uint8_t type;
+ int32_t abs_x;
+ int32_t abs_y;
+ int32_t rel_z;
+};
+
+/*
+ * Multi-touch event and its sub-types
+ *
+ * All multi-touch event packets have common header:
+ *
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | event_type | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ *
+ * event_type - unt8_t, multi-touch event sub-type, XENKBD_MT_EV_???
+ * contact_id - unt8_t, ID of the contact
+ *
+ * Touch interactions can consist of one or more contacts.
+ * For each contact, a series of events is generated, starting
+ * with a down event, followed by zero or more motion events,
+ * and ending with an up event. Events relating to the same
+ * contact point can be identified by the ID of the sequence: contact ID.
+ * Contact ID may be reused after XENKBD_MT_EV_UP event and
+ * is in the [0; XENKBD_FIELD_NUM_CONTACTS - 1] range.
+ *
+ * For further information please refer to documentation on Wayland [1],
+ * Linux [2] and Windows [3] multi-touch support.
+ *
+ * [1] https://cgit.freedesktop.org/wayland/wayland/tree/protocol/wayland.xml
+ * [2] https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt
+ * [3] https://msdn.microsoft.com/en-us/library/jj151564(v=vs.85).aspx
+ *
+ *
+ * Multi-touch down event - sent when a new touch is made: touch is assigned
+ * a unique contact ID, sent with this and consequent events related
+ * to this touch.
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | _MT_EV_DOWN | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | abs_x | 12
+ * +----------------+----------------+----------------+----------------+
+ * | abs_y | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * abs_x - int32_t, absolute X position, in pixels
+ * abs_y - int32_t, absolute Y position, in pixels
+ *
+ * Multi-touch contact release event
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | _MT_EV_UP | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Multi-touch motion event
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | _MT_EV_MOTION | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | abs_x | 12
+ * +----------------+----------------+----------------+----------------+
+ * | abs_y | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * abs_x - int32_t, absolute X position, in pixels,
+ * abs_y - int32_t, absolute Y position, in pixels,
+ *
+ * Multi-touch input synchronization event - shows end of a set of events
+ * which logically belong together.
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | _MT_EV_SYN | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Multi-touch shape event - touch point's shape has changed its shape.
+ * Shape is approximated by an ellipse through the major and minor axis
+ * lengths: major is the longer diameter of the ellipse and minor is the
+ * shorter one. Center of the ellipse is reported via
+ * XENKBD_MT_EV_DOWN/XENKBD_MT_EV_MOTION events.
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | _MT_EV_SHAPE | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | major | 12
+ * +----------------+----------------+----------------+----------------+
+ * | minor | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * major - unt32_t, length of the major axis, pixels
+ * minor - unt32_t, length of the minor axis, pixels
+ *
+ * Multi-touch orientation event - touch point's shape has changed
+ * its orientation: calculated as a clockwise angle between the major axis
+ * of the ellipse and positive Y axis in degrees, [-180; +180].
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | _MT_EV_ORIENT | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | orientation | reserved | 12
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 16
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * orientation - int16_t, clockwise angle of the major axis
+ */
+
+struct xenkbd_mtouch {
+ uint8_t type; /* XENKBD_TYPE_MTOUCH */
+ uint8_t event_type; /* XENKBD_MT_EV_??? */
+ uint8_t contact_id;
+ uint8_t reserved[5]; /* reserved for the future use */
+ union {
+ struct {
+ int32_t abs_x; /* absolute X position, pixels */
+ int32_t abs_y; /* absolute Y position, pixels */
+ } pos;
+ struct {
+ uint32_t major; /* length of the major axis, pixels */
+ uint32_t minor; /* length of the minor axis, pixels */
+ } shape;
+ int16_t orientation; /* clockwise angle of the major axis */
+ } u;
};
#define XENKBD_IN_EVENT_SIZE 40
@@ -72,15 +461,26 @@ union xenkbd_in_event {
struct xenkbd_motion motion;
struct xenkbd_key key;
struct xenkbd_position pos;
+ struct xenkbd_mtouch mtouch;
char pad[XENKBD_IN_EVENT_SIZE];
};
-/* Out events (frontend -> backend) */
-
/*
+ *****************************************************************************
+ * Frontend to backend events
+ *****************************************************************************
+ *
* Out events may be sent only when requested by backend, and receipt
* of an unknown out event is an error.
* No out events currently defined.
+
+ * All event packets have the same length (40 octets)
+ * All event packets have common header:
+ * 0 octet
+ * +-----------------+
+ * | type |
+ * +-----------------+
+ * type - uint8_t, event code
*/
#define XENKBD_OUT_EVENT_SIZE 40
@@ -90,7 +490,11 @@ union xenkbd_out_event {
char pad[XENKBD_OUT_EVENT_SIZE];
};
-/* shared page */
+/*
+ *****************************************************************************
+ * Shared page
+ *****************************************************************************
+ */
#define XENKBD_IN_RING_SIZE 2048
#define XENKBD_IN_RING_LEN (XENKBD_IN_RING_SIZE / XENKBD_IN_EVENT_SIZE)
@@ -113,4 +517,4 @@ struct xenkbd_page {
uint32_t out_cons, out_prod;
};
-#endif
+#endif /* __XEN_PUBLIC_IO_KBDIF_H__ */
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h
index 21f4fbd55e48..c79456855539 100644
--- a/include/xen/interface/io/ring.h
+++ b/include/xen/interface/io/ring.h
@@ -283,4 +283,147 @@ struct __name##_back_ring { \
(_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
} while (0)
+
+/*
+ * DEFINE_XEN_FLEX_RING_AND_INTF defines two monodirectional rings and
+ * functions to check if there is data on the ring, and to read and
+ * write to them.
+ *
+ * DEFINE_XEN_FLEX_RING is similar to DEFINE_XEN_FLEX_RING_AND_INTF, but
+ * does not define the indexes page. As different protocols can have
+ * extensions to the basic format, this macro allow them to define their
+ * own struct.
+ *
+ * XEN_FLEX_RING_SIZE
+ * Convenience macro to calculate the size of one of the two rings
+ * from the overall order.
+ *
+ * $NAME_mask
+ * Function to apply the size mask to an index, to reduce the index
+ * within the range [0-size].
+ *
+ * $NAME_read_packet
+ * Function to read data from the ring. The amount of data to read is
+ * specified by the "size" argument.
+ *
+ * $NAME_write_packet
+ * Function to write data to the ring. The amount of data to write is
+ * specified by the "size" argument.
+ *
+ * $NAME_get_ring_ptr
+ * Convenience function that returns a pointer to read/write to the
+ * ring at the right location.
+ *
+ * $NAME_data_intf
+ * Indexes page, shared between frontend and backend. It also
+ * contains the array of grant refs.
+ *
+ * $NAME_queued
+ * Function to calculate how many bytes are currently on the ring,
+ * ready to be read. It can also be used to calculate how much free
+ * space is currently on the ring (XEN_FLEX_RING_SIZE() -
+ * $NAME_queued()).
+ */
+
+#ifndef XEN_PAGE_SHIFT
+/* The PAGE_SIZE for ring protocols and hypercall interfaces is always
+ * 4K, regardless of the architecture, and page granularity chosen by
+ * operating systems.
+ */
+#define XEN_PAGE_SHIFT 12
+#endif
+#define XEN_FLEX_RING_SIZE(order) \
+ (1UL << ((order) + XEN_PAGE_SHIFT - 1))
+
+#define DEFINE_XEN_FLEX_RING(name) \
+static inline RING_IDX name##_mask(RING_IDX idx, RING_IDX ring_size) \
+{ \
+ return idx & (ring_size - 1); \
+} \
+ \
+static inline unsigned char *name##_get_ring_ptr(unsigned char *buf, \
+ RING_IDX idx, \
+ RING_IDX ring_size) \
+{ \
+ return buf + name##_mask(idx, ring_size); \
+} \
+ \
+static inline void name##_read_packet(void *opaque, \
+ const unsigned char *buf, \
+ size_t size, \
+ RING_IDX masked_prod, \
+ RING_IDX *masked_cons, \
+ RING_IDX ring_size) \
+{ \
+ if (*masked_cons < masked_prod || \
+ size <= ring_size - *masked_cons) { \
+ memcpy(opaque, buf + *masked_cons, size); \
+ } else { \
+ memcpy(opaque, buf + *masked_cons, ring_size - *masked_cons); \
+ memcpy((unsigned char *)opaque + ring_size - *masked_cons, buf, \
+ size - (ring_size - *masked_cons)); \
+ } \
+ *masked_cons = name##_mask(*masked_cons + size, ring_size); \
+} \
+ \
+static inline void name##_write_packet(unsigned char *buf, \
+ const void *opaque, \
+ size_t size, \
+ RING_IDX *masked_prod, \
+ RING_IDX masked_cons, \
+ RING_IDX ring_size) \
+{ \
+ if (*masked_prod < masked_cons || \
+ size <= ring_size - *masked_prod) { \
+ memcpy(buf + *masked_prod, opaque, size); \
+ } else { \
+ memcpy(buf + *masked_prod, opaque, ring_size - *masked_prod); \
+ memcpy(buf, (unsigned char *)opaque + (ring_size - *masked_prod), \
+ size - (ring_size - *masked_prod)); \
+ } \
+ *masked_prod = name##_mask(*masked_prod + size, ring_size); \
+} \
+ \
+static inline RING_IDX name##_queued(RING_IDX prod, \
+ RING_IDX cons, \
+ RING_IDX ring_size) \
+{ \
+ RING_IDX size; \
+ \
+ if (prod == cons) \
+ return 0; \
+ \
+ prod = name##_mask(prod, ring_size); \
+ cons = name##_mask(cons, ring_size); \
+ \
+ if (prod == cons) \
+ return ring_size; \
+ \
+ if (prod > cons) \
+ size = prod - cons; \
+ else \
+ size = ring_size - (cons - prod); \
+ return size; \
+} \
+ \
+struct name##_data { \
+ unsigned char *in; /* half of the allocation */ \
+ unsigned char *out; /* half of the allocation */ \
+}
+
+#define DEFINE_XEN_FLEX_RING_AND_INTF(name) \
+struct name##_data_intf { \
+ RING_IDX in_cons, in_prod; \
+ \
+ uint8_t pad1[56]; \
+ \
+ RING_IDX out_cons, out_prod; \
+ \
+ uint8_t pad2[56]; \
+ \
+ RING_IDX ring_order; \
+ grant_ref_t ref[]; \
+}; \
+DEFINE_XEN_FLEX_RING(name)
+
#endif /* __XEN_PUBLIC_IO_RING_H__ */
diff --git a/include/xen/interface/io/sndif.h b/include/xen/interface/io/sndif.h
new file mode 100644
index 000000000000..5c918276835e
--- /dev/null
+++ b/include/xen/interface/io/sndif.h
@@ -0,0 +1,793 @@
+/******************************************************************************
+ * sndif.h
+ *
+ * Unified sound-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) 2013-2015 GlobalLogic Inc.
+ * Copyright (C) 2016-2017 EPAM Systems Inc.
+ *
+ * Authors: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
+ * Oleksandr Grytsov <oleksandr_grytsov@epam.com>
+ * Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
+ * Iurii Konovalenko <iurii.konovalenko@globallogic.com>
+ */
+
+#ifndef __XEN_PUBLIC_IO_SNDIF_H__
+#define __XEN_PUBLIC_IO_SNDIF_H__
+
+#include "ring.h"
+#include "../grant_table.h"
+
+/*
+ ******************************************************************************
+ * Feature and Parameter Negotiation
+ ******************************************************************************
+ *
+ * Front->back notifications: when enqueuing a new request, sending a
+ * notification can be made conditional on xensnd_req (i.e., the generic
+ * hold-off mechanism provided by the ring macros). Backends must set
+ * xensnd_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 xensnd_resp (i.e., the generic
+ * hold-off mechanism provided by the ring macros). Frontends must set
+ * xensnd_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
+ *
+ * The two halves of a para-virtual sound card 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 formated node string, without loss of information.
+ *
+ ******************************************************************************
+ * Example configuration
+ ******************************************************************************
+ *
+ * Note: depending on the use-case backend can expose more sound cards and
+ * PCM devices/streams than the underlying HW physically has by employing
+ * SW mixers, configuring virtual sound streams, channels etc.
+ *
+ * This is an example of backend and frontend configuration:
+ *
+ *--------------------------------- Backend -----------------------------------
+ *
+ * /local/domain/0/backend/vsnd/1/0/frontend-id = "1"
+ * /local/domain/0/backend/vsnd/1/0/frontend = "/local/domain/1/device/vsnd/0"
+ * /local/domain/0/backend/vsnd/1/0/state = "4"
+ * /local/domain/0/backend/vsnd/1/0/versions = "1,2"
+ *
+ *--------------------------------- Frontend ----------------------------------
+ *
+ * /local/domain/1/device/vsnd/0/backend-id = "0"
+ * /local/domain/1/device/vsnd/0/backend = "/local/domain/0/backend/vsnd/1/0"
+ * /local/domain/1/device/vsnd/0/state = "4"
+ * /local/domain/1/device/vsnd/0/version = "1"
+ *
+ *----------------------------- Card configuration ----------------------------
+ *
+ * /local/domain/1/device/vsnd/0/short-name = "Card short name"
+ * /local/domain/1/device/vsnd/0/long-name = "Card long name"
+ * /local/domain/1/device/vsnd/0/sample-rates = "8000,32000,44100,48000,96000"
+ * /local/domain/1/device/vsnd/0/sample-formats = "s8,u8,s16_le,s16_be"
+ * /local/domain/1/device/vsnd/0/buffer-size = "262144"
+ *
+ *------------------------------- PCM device 0 --------------------------------
+ *
+ * /local/domain/1/device/vsnd/0/0/name = "General analog"
+ * /local/domain/1/device/vsnd/0/0/channels-max = "5"
+ *
+ *----------------------------- Stream 0, playback ----------------------------
+ *
+ * /local/domain/1/device/vsnd/0/0/0/type = "p"
+ * /local/domain/1/device/vsnd/0/0/0/sample-formats = "s8,u8"
+ * /local/domain/1/device/vsnd/0/0/0/unique-id = "0"
+ *
+ * /local/domain/1/device/vsnd/0/0/0/ring-ref = "386"
+ * /local/domain/1/device/vsnd/0/0/0/event-channel = "15"
+ *
+ *------------------------------ Stream 1, capture ----------------------------
+ *
+ * /local/domain/1/device/vsnd/0/0/1/type = "c"
+ * /local/domain/1/device/vsnd/0/0/1/channels-max = "2"
+ * /local/domain/1/device/vsnd/0/0/1/unique-id = "1"
+ *
+ * /local/domain/1/device/vsnd/0/0/1/ring-ref = "384"
+ * /local/domain/1/device/vsnd/0/0/1/event-channel = "13"
+ *
+ *------------------------------- PCM device 1 --------------------------------
+ *
+ * /local/domain/1/device/vsnd/0/1/name = "HDMI-0"
+ * /local/domain/1/device/vsnd/0/1/sample-rates = "8000,32000,44100"
+ *
+ *------------------------------ Stream 0, capture ----------------------------
+ *
+ * /local/domain/1/device/vsnd/0/1/0/type = "c"
+ * /local/domain/1/device/vsnd/0/1/0/unique-id = "2"
+ *
+ * /local/domain/1/device/vsnd/0/1/0/ring-ref = "387"
+ * /local/domain/1/device/vsnd/0/1/0/event-channel = "151"
+ *
+ *------------------------------- PCM device 2 --------------------------------
+ *
+ * /local/domain/1/device/vsnd/0/2/name = "SPDIF"
+ *
+ *----------------------------- Stream 0, playback ----------------------------
+ *
+ * /local/domain/1/device/vsnd/0/2/0/type = "p"
+ * /local/domain/1/device/vsnd/0/2/0/unique-id = "3"
+ *
+ * /local/domain/1/device/vsnd/0/2/0/ring-ref = "389"
+ * /local/domain/1/device/vsnd/0/2/0/event-channel = "152"
+ *
+ ******************************************************************************
+ * Backend XenBus Nodes
+ ******************************************************************************
+ *
+ *----------------------------- Protocol version ------------------------------
+ *
+ * versions
+ * Values: <string>
+ *
+ * List of XENSND_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.
+ *
+ * pcm-dev-idx
+ * Values: <uint8_t>
+ *
+ * Zero based contigous index of the PCM device.
+ *
+ * stream-idx
+ * Values: <uint8_t>
+ *
+ * Zero based contigous index of the stream of the PCM device.
+ *
+ * The following pattern is used for addressing:
+ * /local/domain/<dom-id>/device/vsnd/<dev-id>/<pcm-dev-idx>/<stream-idx>/...
+ *
+ *----------------------------- Protocol version ------------------------------
+ *
+ * version
+ * Values: <string>
+ *
+ * Protocol version, chosen among the ones supported by the backend.
+ *
+ *------------------------------- PCM settings --------------------------------
+ *
+ * Every virtualized sound frontend has a set of PCM devices and streams, each
+ * could be individually configured. Part of the PCM configuration can be
+ * defined at higher level of the hierarchy and be fully or partially re-used
+ * by the underlying layers. These configuration values are:
+ * o number of channels (min/max)
+ * o supported sample rates
+ * o supported sample formats.
+ * E.g. one can define these values for the whole card, device or stream.
+ * Every underlying layer in turn can re-define some or all of them to better
+ * fit its needs. For example, card may define number of channels to be
+ * in [1; 8] range, and some particular stream may be limited to [1; 2] only.
+ * The rule is that the underlying layer must be a subset of the upper layer
+ * range.
+ *
+ * channels-min
+ * Values: <uint8_t>
+ *
+ * The minimum amount of channels that is supported, [1; channels-max].
+ * Optional, if not set or omitted a value of 1 is used.
+ *
+ * channels-max
+ * Values: <uint8_t>
+ *
+ * The maximum amount of channels that is supported.
+ * Must be at least <channels-min>.
+ *
+ * sample-rates
+ * Values: <list of uint32_t>
+ *
+ * List of supported sample rates separated by XENSND_LIST_SEPARATOR.
+ * Sample rates are expressed as a list of decimal values w/o any
+ * ordering requirement.
+ *
+ * sample-formats
+ * Values: <list of XENSND_PCM_FORMAT_XXX_STR>
+ *
+ * List of supported sample formats separated by XENSND_LIST_SEPARATOR.
+ * Items must not exceed XENSND_SAMPLE_FORMAT_MAX_LEN length.
+ *
+ * buffer-size
+ * Values: <uint32_t>
+ *
+ * The maximum size in octets of the buffer to allocate per stream.
+ *
+ *----------------------- Virtual sound card settings -------------------------
+ * short-name
+ * Values: <char[32]>
+ *
+ * Short name of the virtual sound card. Optional.
+ *
+ * long-name
+ * Values: <char[80]>
+ *
+ * Long name of the virtual sound card. Optional.
+ *
+ *----------------------------- Device settings -------------------------------
+ * name
+ * Values: <char[80]>
+ *
+ * Name of the sound device within the virtual sound card. Optional.
+ *
+ *----------------------------- Stream settings -------------------------------
+ *
+ * type
+ * Values: "p", "c"
+ *
+ * Stream type: "p" - playback stream, "c" - capture stream
+ *
+ * If both capture and playback are needed then two streams need to be
+ * defined under the same device.
+ *
+ * unique-id
+ * Values: <uint32_t>
+ *
+ * After stream initialization it is assigned a unique ID (within the front
+ * driver), so every stream of the frontend can be identified by the
+ * backend by this ID. This is not equal to stream-idx as the later is
+ * zero based within the device, but this index is contigous within the
+ * driver.
+ *
+ *-------------------- Stream Request Transport Parameters --------------------
+ *
+ * event-channel
+ * Values: <uint32_t>
+ *
+ * The identifier of the Xen event channel used to signal activity
+ * in the ring buffer.
+ *
+ * ring-ref
+ * Values: <uint32_t>
+ *
+ * The Xen grant reference granting permission for the backend to map
+ * a sole page in a single page sized ring buffer.
+ *
+ ******************************************************************************
+ * STATE DIAGRAMS
+ ******************************************************************************
+ *
+ * Tool stack creates front and back state nodes with initial state
+ * XenbusStateInitialising.
+ * Tool stack creates and sets up frontend sound configuration nodes per domain.
+ *
+ * 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
+ * playback/capture stream.
+ * 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 sound device instances
+ * as per configuration.
+ * |
+ * |
+ * V
+ * XenbusStateConnected
+ *
+ * XenbusStateUnknown
+ * XenbusStateClosed
+ * XenbusStateClosing
+ * o Remove virtual sound 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 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.
+ * So, 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.
+ *
+ ******************************************************************************
+ * PCM FORMATS
+ ******************************************************************************
+ *
+ * XENSND_PCM_FORMAT_<format>[_<endian>]
+ *
+ * format: <S/U/F><bits> or <name>
+ * S - signed, U - unsigned, F - float
+ * bits - 8, 16, 24, 32
+ * name - MU_LAW, GSM, etc.
+ *
+ * endian: <LE/BE>, may be absent
+ * LE - Little endian, BE - Big endian
+ */
+#define XENSND_PCM_FORMAT_S8 0
+#define XENSND_PCM_FORMAT_U8 1
+#define XENSND_PCM_FORMAT_S16_LE 2
+#define XENSND_PCM_FORMAT_S16_BE 3
+#define XENSND_PCM_FORMAT_U16_LE 4
+#define XENSND_PCM_FORMAT_U16_BE 5
+#define XENSND_PCM_FORMAT_S24_LE 6
+#define XENSND_PCM_FORMAT_S24_BE 7
+#define XENSND_PCM_FORMAT_U24_LE 8
+#define XENSND_PCM_FORMAT_U24_BE 9
+#define XENSND_PCM_FORMAT_S32_LE 10
+#define XENSND_PCM_FORMAT_S32_BE 11
+#define XENSND_PCM_FORMAT_U32_LE 12
+#define XENSND_PCM_FORMAT_U32_BE 13
+#define XENSND_PCM_FORMAT_F32_LE 14 /* 4-byte float, IEEE-754 32-bit, */
+#define XENSND_PCM_FORMAT_F32_BE 15 /* range -1.0 to 1.0 */
+#define XENSND_PCM_FORMAT_F64_LE 16 /* 8-byte float, IEEE-754 64-bit, */
+#define XENSND_PCM_FORMAT_F64_BE 17 /* range -1.0 to 1.0 */
+#define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE 18
+#define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE 19
+#define XENSND_PCM_FORMAT_MU_LAW 20
+#define XENSND_PCM_FORMAT_A_LAW 21
+#define XENSND_PCM_FORMAT_IMA_ADPCM 22
+#define XENSND_PCM_FORMAT_MPEG 23
+#define XENSND_PCM_FORMAT_GSM 24
+
+/*
+ ******************************************************************************
+ * REQUEST CODES
+ ******************************************************************************
+ */
+#define XENSND_OP_OPEN 0
+#define XENSND_OP_CLOSE 1
+#define XENSND_OP_READ 2
+#define XENSND_OP_WRITE 3
+#define XENSND_OP_SET_VOLUME 4
+#define XENSND_OP_GET_VOLUME 5
+#define XENSND_OP_MUTE 6
+#define XENSND_OP_UNMUTE 7
+
+/*
+ ******************************************************************************
+ * XENSTORE FIELD AND PATH NAME STRINGS, HELPERS
+ ******************************************************************************
+ */
+#define XENSND_DRIVER_NAME "vsnd"
+
+#define XENSND_LIST_SEPARATOR ","
+/* Field names */
+#define XENSND_FIELD_BE_VERSIONS "versions"
+#define XENSND_FIELD_FE_VERSION "version"
+#define XENSND_FIELD_VCARD_SHORT_NAME "short-name"
+#define XENSND_FIELD_VCARD_LONG_NAME "long-name"
+#define XENSND_FIELD_RING_REF "ring-ref"
+#define XENSND_FIELD_EVT_CHNL "event-channel"
+#define XENSND_FIELD_DEVICE_NAME "name"
+#define XENSND_FIELD_TYPE "type"
+#define XENSND_FIELD_STREAM_UNIQUE_ID "unique-id"
+#define XENSND_FIELD_CHANNELS_MIN "channels-min"
+#define XENSND_FIELD_CHANNELS_MAX "channels-max"
+#define XENSND_FIELD_SAMPLE_RATES "sample-rates"
+#define XENSND_FIELD_SAMPLE_FORMATS "sample-formats"
+#define XENSND_FIELD_BUFFER_SIZE "buffer-size"
+
+/* Stream type field values. */
+#define XENSND_STREAM_TYPE_PLAYBACK "p"
+#define XENSND_STREAM_TYPE_CAPTURE "c"
+/* Sample rate max string length */
+#define XENSND_SAMPLE_RATE_MAX_LEN 11
+/* Sample format field values */
+#define XENSND_SAMPLE_FORMAT_MAX_LEN 24
+
+#define XENSND_PCM_FORMAT_S8_STR "s8"
+#define XENSND_PCM_FORMAT_U8_STR "u8"
+#define XENSND_PCM_FORMAT_S16_LE_STR "s16_le"
+#define XENSND_PCM_FORMAT_S16_BE_STR "s16_be"
+#define XENSND_PCM_FORMAT_U16_LE_STR "u16_le"
+#define XENSND_PCM_FORMAT_U16_BE_STR "u16_be"
+#define XENSND_PCM_FORMAT_S24_LE_STR "s24_le"
+#define XENSND_PCM_FORMAT_S24_BE_STR "s24_be"
+#define XENSND_PCM_FORMAT_U24_LE_STR "u24_le"
+#define XENSND_PCM_FORMAT_U24_BE_STR "u24_be"
+#define XENSND_PCM_FORMAT_S32_LE_STR "s32_le"
+#define XENSND_PCM_FORMAT_S32_BE_STR "s32_be"
+#define XENSND_PCM_FORMAT_U32_LE_STR "u32_le"
+#define XENSND_PCM_FORMAT_U32_BE_STR "u32_be"
+#define XENSND_PCM_FORMAT_F32_LE_STR "float_le"
+#define XENSND_PCM_FORMAT_F32_BE_STR "float_be"
+#define XENSND_PCM_FORMAT_F64_LE_STR "float64_le"
+#define XENSND_PCM_FORMAT_F64_BE_STR "float64_be"
+#define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE_STR "iec958_subframe_le"
+#define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE_STR "iec958_subframe_be"
+#define XENSND_PCM_FORMAT_MU_LAW_STR "mu_law"
+#define XENSND_PCM_FORMAT_A_LAW_STR "a_law"
+#define XENSND_PCM_FORMAT_IMA_ADPCM_STR "ima_adpcm"
+#define XENSND_PCM_FORMAT_MPEG_STR "mpeg"
+#define XENSND_PCM_FORMAT_GSM_STR "gsm"
+
+
+/*
+ ******************************************************************************
+ * STATUS RETURN CODES
+ ******************************************************************************
+ *
+ * Status return code is zero on success and -XEN_EXX on failure.
+ *
+ ******************************************************************************
+ * Assumptions
+ ******************************************************************************
+ * o 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.
+ * o all references in this document to page sizes must be treated
+ * as pages of size XEN_PAGE_SIZE unless otherwise noted.
+ *
+ ******************************************************************************
+ * Description of the protocol between frontend and backend driver
+ ******************************************************************************
+ *
+ * The two halves of a Para-virtual sound driver communicate with
+ * each other using shared pages and event channels.
+ * Shared page contains a ring with request/response packets.
+ *
+ * Packets, used for input/output operations, e.g. read/write, set/get volume,
+ * etc., provide offset/length fields in order to allow asynchronous protocol
+ * operation with buffer space sharing: part of the buffer allocated at
+ * XENSND_OP_OPEN can be used for audio samples and part, for example,
+ * for volume control.
+ *
+ * All reserved fields in the structures below must be 0.
+ *
+ *---------------------------------- Requests ---------------------------------
+ *
+ * All request packets have the same length (32 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, XENSND_OP_???
+ *
+ * For all packets which use offset and length:
+ * offset - uint32_t, read or write data offset within the shared buffer,
+ * passed with XENSND_OP_OPEN request, octets,
+ * [0; XENSND_OP_OPEN.buffer_sz - 1].
+ * length - uint32_t, read or write data length, octets
+ *
+ * Request open - open a PCM stream for playback or capture:
+ *
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id | XENSND_OP_OPEN | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | pcm_rate | 12
+ * +----------------+----------------+----------------+----------------+
+ * | pcm_format | pcm_channels | reserved | 16
+ * +----------------+----------------+----------------+----------------+
+ * | buffer_sz | 20
+ * +----------------+----------------+----------------+----------------+
+ * | gref_directory | 24
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 28
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 32
+ * +----------------+----------------+----------------+----------------+
+ *
+ * pcm_rate - uint32_t, stream data rate, Hz
+ * pcm_format - uint8_t, XENSND_PCM_FORMAT_XXX value
+ * pcm_channels - uint8_t, number of channels of this stream,
+ * [channels-min; channels-max]
+ * buffer_sz - uint32_t, buffer size to be allocated, octets
+ * gref_directory - grant_ref_t, a reference to the first shared page
+ * describing shared buffer references. At least one page exists. If shared
+ * buffer size (buffer_sz) exceeds what can be addressed by this single page,
+ * then reference to the next page must be supplied (see gref_dir_next_page
+ * below)
+ */
+
+struct xensnd_open_req {
+ uint32_t pcm_rate;
+ uint8_t pcm_format;
+ uint8_t pcm_channels;
+ uint16_t reserved;
+ uint32_t buffer_sz;
+ grant_ref_t gref_directory;
+};
+
+/*
+ * Shared page for XENSND_OP_OPEN 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 XENSND_OP_OPEN
+ *
+ * Number of grant_ref_t entries in the whole page directory is not
+ * passed, but instead can be calculated as:
+ * num_grefs_total = (XENSND_OP_OPEN.buffer_sz + XEN_PAGE_SIZE - 1) /
+ * XEN_PAGE_SIZE
+ */
+
+struct xensnd_page_directory {
+ grant_ref_t gref_dir_next_page;
+ grant_ref_t gref[1]; /* Variable length */
+};
+
+/*
+ * Request close - close an opened pcm stream:
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id | XENSND_OP_CLOSE| reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 32
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Request read/write - used for read (for capture) or write (for playback):
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id | operation | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | offset | 12
+ * +----------------+----------------+----------------+----------------+
+ * | length | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 32
+ * +----------------+----------------+----------------+----------------+
+ *
+ * operation - XENSND_OP_READ for read or XENSND_OP_WRITE for write
+ */
+
+struct xensnd_rw_req {
+ uint32_t offset;
+ uint32_t length;
+};
+
+/*
+ * Request set/get volume - set/get channels' volume of the stream given:
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id | operation | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | offset | 12
+ * +----------------+----------------+----------------+----------------+
+ * | length | 16
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 32
+ * +----------------+----------------+----------------+----------------+
+ *
+ * operation - XENSND_OP_SET_VOLUME for volume set
+ * or XENSND_OP_GET_VOLUME for volume get
+ * Buffer passed with XENSND_OP_OPEN is used to exchange volume
+ * values:
+ *
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | channel[0] | 4
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | channel[i] | i*4
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | channel[N - 1] | (N-1)*4
+ * +----------------+----------------+----------------+----------------+
+ *
+ * N = XENSND_OP_OPEN.pcm_channels
+ * i - uint8_t, index of a channel
+ * channel[i] - sint32_t, volume of i-th channel
+ * Volume is expressed as a signed value in steps of 0.001 dB,
+ * while 0 being 0 dB.
+ *
+ * Request mute/unmute - mute/unmute stream:
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id | operation | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | offset | 12
+ * +----------------+----------------+----------------+----------------+
+ * | length | 16
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 32
+ * +----------------+----------------+----------------+----------------+
+ *
+ * operation - XENSND_OP_MUTE for mute or XENSND_OP_UNMUTE for unmute
+ * Buffer passed with XENSND_OP_OPEN is used to exchange mute/unmute
+ * values:
+ *
+ * 0 octet
+ * +----------------+----------------+----------------+----------------+
+ * | channel[0] | 4
+ * +----------------+----------------+----------------+----------------+
+ * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | channel[i] | i*4
+ * +----------------+----------------+----------------+----------------+
+ * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | channel[N - 1] | (N-1)*4
+ * +----------------+----------------+----------------+----------------+
+ *
+ * N = XENSND_OP_OPEN.pcm_channels
+ * i - uint8_t, index of a channel
+ * channel[i] - uint8_t, non-zero if i-th channel needs to be muted/unmuted
+ *
+ *------------------------------------ N.B. -----------------------------------
+ *
+ * The 'struct xensnd_rw_req' is also used for XENSND_OP_SET_VOLUME,
+ * XENSND_OP_GET_VOLUME, XENSND_OP_MUTE, XENSND_OP_UNMUTE.
+ */
+
+/*
+ *---------------------------------- Responses --------------------------------
+ *
+ * All response packets have the same length (32 octets)
+ *
+ * Response for all requests:
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | id | operation | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | status | 8
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 12
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 32
+ * +----------------+----------------+----------------+----------------+
+ *
+ * id - uint16_t, copied from the request
+ * operation - uint8_t, XENSND_OP_* - copied from request
+ * status - int32_t, response status, zero on success and -XEN_EXX on failure
+ */
+
+struct xensnd_req {
+ uint16_t id;
+ uint8_t operation;
+ uint8_t reserved[5];
+ union {
+ struct xensnd_open_req open;
+ struct xensnd_rw_req rw;
+ uint8_t reserved[24];
+ } op;
+};
+
+struct xensnd_resp {
+ uint16_t id;
+ uint8_t operation;
+ uint8_t reserved;
+ int32_t status;
+ uint8_t reserved1[24];
+};
+
+DEFINE_RING_TYPES(xen_sndif, struct xensnd_req, struct xensnd_resp);
+
+#endif /* __XEN_PUBLIC_IO_SNDIF_H__ */
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
index b5486e648607..c44a2ee8c8f8 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
@@ -22,6 +22,8 @@ void xen_timer_resume(void);
void xen_arch_resume(void);
void xen_arch_suspend(void);
+void xen_reboot(int reason);
+
void xen_resume_notifier_register(struct notifier_block *nb);
void xen_resume_notifier_unregister(struct notifier_block *nb);
@@ -34,11 +36,25 @@ u64 xen_steal_clock(int cpu);
int xen_setup_shutdown_event(void);
extern unsigned long *xen_contiguous_bitmap;
+
+#ifdef CONFIG_XEN_PV
int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
unsigned int address_bits,
dma_addr_t *dma_handle);
void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order);
+#else
+static inline int xen_create_contiguous_region(phys_addr_t pstart,
+ unsigned int order,
+ unsigned int address_bits,
+ dma_addr_t *dma_handle)
+{
+ return 0;
+}
+
+static inline void xen_destroy_contiguous_region(phys_addr_t pstart,
+ unsigned int order) { }
+#endif
struct vm_area_struct;
@@ -120,6 +136,9 @@ efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
unsigned long count, u64 *max_size,
int *reset_type);
+void xen_efi_reset_system(int reset_type, efi_status_t status,
+ unsigned long data_size, efi_char16_t *data);
+
#ifdef CONFIG_PREEMPT