diff options
Diffstat (limited to 'include/xen/interface/io/usbif.h')
| -rw-r--r-- | include/xen/interface/io/usbif.h | 405 | 
1 files changed, 405 insertions, 0 deletions
| diff --git a/include/xen/interface/io/usbif.h b/include/xen/interface/io/usbif.h new file mode 100644 index 000000000000..a70e0b93178b --- /dev/null +++ b/include/xen/interface/io/usbif.h @@ -0,0 +1,405 @@ +/* SPDX-License-Identifier: MIT */ + +/* + * usbif.h + * + * USB I/O interface for Xen guest OSes. + * + * Copyright (C) 2009, FUJITSU LABORATORIES LTD. + * Author: Noboru Iwamatsu <[email protected]> + */ + +#ifndef __XEN_PUBLIC_IO_USBIF_H__ +#define __XEN_PUBLIC_IO_USBIF_H__ + +#include "ring.h" +#include "../grant_table.h" + +/* + * Detailed Interface Description + * ============================== + * The pvUSB interface is using a split driver design: a frontend driver in + * the guest and a backend driver in a driver domain (normally dom0) having + * access to the physical USB device(s) being passed to the guest. + * + * The frontend and backend drivers use XenStore to initiate the connection + * between them, the I/O activity is handled via two shared ring pages and an + * event channel. As the interface between frontend and backend is at the USB + * host connector level, multiple (up to 31) physical USB devices can be + * handled by a single connection. + * + * The Xen pvUSB device name is "qusb", so the frontend's XenStore entries are + * to be found under "device/qusb", while the backend's XenStore entries are + * under "backend/<guest-dom-id>/qusb". + * + * When a new pvUSB connection is established, the frontend needs to setup the + * two shared ring pages for communication and the event channel. The ring + * pages need to be made available to the backend via the grant table + * interface. + * + * One of the shared ring pages is used by the backend to inform the frontend + * about USB device plug events (device to be added or removed). This is the + * "conn-ring". + * + * The other ring page is used for USB I/O communication (requests and + * responses). This is the "urb-ring". + * + * Feature and Parameter Negotiation + * ================================= + * The two halves of a Xen pvUSB driver utilize nodes within the XenStore to + * communicate capabilities and to negotiate operating parameters. This + * section enumerates these nodes which reside in the respective front and + * backend portions of the XenStore, following the XenBus convention. + * + * Any specified default value is in effect if the corresponding XenBus node + * is not present in the XenStore. + * + * XenStore nodes in sections marked "PRIVATE" are solely for use by the + * driver side whose XenBus tree contains them. + * + ***************************************************************************** + *                            Backend XenBus Nodes + ***************************************************************************** + * + *------------------ Backend Device Identification (PRIVATE) ------------------ + * + * num-ports + *      Values:         unsigned [1...31] + * + *      Number of ports for this (virtual) USB host connector. + * + * usb-ver + *      Values:         unsigned [1...2] + * + *      USB version of this host connector: 1 = USB 1.1, 2 = USB 2.0. + * + * port/[1...31] + *      Values:         string + * + *      Physical USB device connected to the given port, e.g. "3-1.5". + * + ***************************************************************************** + *                            Frontend XenBus Nodes + ***************************************************************************** + * + *----------------------- Request Transport Parameters ----------------------- + * + * event-channel + *      Values:         unsigned + * + *      The identifier of the Xen event channel used to signal activity + *      in the ring buffer. + * + * urb-ring-ref + *      Values:         unsigned + * + *      The Xen grant reference granting permission for the backend to map + *      the sole page in a single page sized ring buffer. This is the ring + *      buffer for urb requests. + * + * conn-ring-ref + *      Values:         unsigned + * + *      The Xen grant reference granting permission for the backend to map + *      the sole page in a single page sized ring buffer. This is the ring + *      buffer for connection/disconnection requests. + * + * protocol + *      Values:         string (XEN_IO_PROTO_ABI_*) + *      Default Value:  XEN_IO_PROTO_ABI_NATIVE + * + *      The machine ABI rules governing the format of all ring request and + *      response structures. + * + * Protocol Description + * ==================== + * + *-------------------------- USB device plug events -------------------------- + * + * USB device plug events are send via the "conn-ring" shared page. As only + * events are being sent, the respective requests from the frontend to the + * backend are just dummy ones. + * The events sent to the frontend have the following layout: + *         0                1                 2               3        octet + * +----------------+----------------+----------------+----------------+ + * |               id                |    portnum     |     speed      | 4 + * +----------------+----------------+----------------+----------------+ + *   id - uint16_t, event id (taken from the actual frontend dummy request) + *   portnum - uint8_t, port number (1 ... 31) + *   speed - uint8_t, device XENUSB_SPEED_*, XENUSB_SPEED_NONE == unplug + * + * The dummy request: + *         0                1        octet + * +----------------+----------------+ + * |               id                | 2 + * +----------------+----------------+ + *   id - uint16_t, guest supplied value (no need for being unique) + * + *-------------------------- USB I/O request --------------------------------- + * + * A single USB I/O request on the "urb-ring" has the following layout: + *         0                1                 2               3        octet + * +----------------+----------------+----------------+----------------+ + * |               id                |         nr_buffer_segs          | 4 + * +----------------+----------------+----------------+----------------+ + * |                               pipe                                | 8 + * +----------------+----------------+----------------+----------------+ + * |         transfer_flags          |          buffer_length          | 12 + * +----------------+----------------+----------------+----------------+ + * |                       request type specific                       | 16 + * |                               data                                | 20 + * +----------------+----------------+----------------+----------------+ + * |                              seg[0]                               | 24 + * |                               data                                | 28 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * |             seg[XENUSB_MAX_SEGMENTS_PER_REQUEST - 1]              | 144 + * |                               data                                | 148 + * +----------------+----------------+----------------+----------------+ + * Bit field bit number 0 is always least significant bit, undefined bits must + * be zero. + *   id - uint16_t, guest supplied value + *   nr_buffer_segs - uint16_t, number of segment entries in seg[] array + *   pipe - uint32_t, bit field with multiple information: + *     bits 0-4: port request to send to + *     bit 5: unlink request with specified id (cancel I/O) if set (see below) + *     bit 7: direction (1 = read from device) + *     bits 8-14: device number on port + *     bits 15-18: endpoint of device + *     bits 30-31: request type: 00 = isochronous, 01 = interrupt, + *                               10 = control, 11 = bulk + *   transfer_flags - uint16_t, bit field with processing flags: + *     bit 0: less data than specified allowed + *   buffer_length - uint16_t, total length of data + *   request type specific data - 8 bytes, see below + *   seg[] - array with 8 byte elements, see below + * + * Request type specific data for isochronous request: + *         0                1                 2               3        octet + * +----------------+----------------+----------------+----------------+ + * |            interval             |           start_frame           | 4 + * +----------------+----------------+----------------+----------------+ + * |       number_of_packets         |       nr_frame_desc_segs        | 8 + * +----------------+----------------+----------------+----------------+ + *   interval - uint16_t, time interval in msecs between frames + *   start_frame - uint16_t, start frame number + *   number_of_packets - uint16_t, number of packets to transfer + *   nr_frame_desc_segs - uint16_t number of seg[] frame descriptors elements + * + * Request type specific data for interrupt request: + *         0                1                 2               3        octet + * +----------------+----------------+----------------+----------------+ + * |            interval             |                0                | 4 + * +----------------+----------------+----------------+----------------+ + * |                                 0                                 | 8 + * +----------------+----------------+----------------+----------------+ + *   interval - uint16_t, time in msecs until interruption + * + * Request type specific data for control request: + *         0                1                 2               3        octet + * +----------------+----------------+----------------+----------------+ + * |                      data of setup packet                         | 4 + * |                                                                   | 8 + * +----------------+----------------+----------------+----------------+ + * + * Request type specific data for bulk request: + *         0                1                 2               3        octet + * +----------------+----------------+----------------+----------------+ + * |                                 0                                 | 4 + * |                                 0                                 | 8 + * +----------------+----------------+----------------+----------------+ + * + * Request type specific data for unlink request: + *         0                1                 2               3        octet + * +----------------+----------------+----------------+----------------+ + * |           unlink_id             |                0                | 4 + * +----------------+----------------+----------------+----------------+ + * |                                 0                                 | 8 + * +----------------+----------------+----------------+----------------+ + *   unlink_id - uint16_t, request id of request to terminate + * + * seg[] array element layout: + *         0                1                 2               3        octet + * +----------------+----------------+----------------+----------------+ + * |                               gref                                | 4 + * +----------------+----------------+----------------+----------------+ + * |             offset              |             length              | 8 + * +----------------+----------------+----------------+----------------+ + *   gref - uint32_t, grant reference of buffer page + *   offset - uint16_t, offset of buffer start in page + *   length - uint16_t, length of buffer in page + * + *-------------------------- USB I/O response -------------------------------- + * + *         0                1                 2               3        octet + * +----------------+----------------+----------------+----------------+ + * |               id                |          start_frame            | 4 + * +----------------+----------------+----------------+----------------+ + * |                              status                               | 8 + * +----------------+----------------+----------------+----------------+ + * |                          actual_length                            | 12 + * +----------------+----------------+----------------+----------------+ + * |                           error_count                             | 16 + * +----------------+----------------+----------------+----------------+ + *   id - uint16_t, id of the request this response belongs to + *   start_frame - uint16_t, start_frame this response (iso requests only) + *   status - int32_t, XENUSB_STATUS_* (non-iso requests) + *   actual_length - uint32_t, actual size of data transferred + *   error_count - uint32_t, number of errors (iso requests) + */ + +enum xenusb_spec_version { +	XENUSB_VER_UNKNOWN = 0, +	XENUSB_VER_USB11, +	XENUSB_VER_USB20, +	XENUSB_VER_USB30,	/* not supported yet */ +}; + +/* + *  USB pipe in xenusb_request + * + *  - port number:      bits 0-4 + *                              (USB_MAXCHILDREN is 31) + * + *  - operation flag:   bit 5 + *                              (0 = submit urb, + *                               1 = unlink urb) + * + *  - direction:        bit 7 + *                              (0 = Host-to-Device [Out] + *                               1 = Device-to-Host [In]) + * + *  - device address:   bits 8-14 + * + *  - endpoint:         bits 15-18 + * + *  - pipe type:        bits 30-31 + *                              (00 = isochronous, 01 = interrupt, + *                               10 = control, 11 = bulk) + */ + +#define XENUSB_PIPE_PORT_MASK	0x0000001f +#define XENUSB_PIPE_UNLINK	0x00000020 +#define XENUSB_PIPE_DIR		0x00000080 +#define XENUSB_PIPE_DEV_MASK	0x0000007f +#define XENUSB_PIPE_DEV_SHIFT	8 +#define XENUSB_PIPE_EP_MASK	0x0000000f +#define XENUSB_PIPE_EP_SHIFT	15 +#define XENUSB_PIPE_TYPE_MASK	0x00000003 +#define XENUSB_PIPE_TYPE_SHIFT	30 +#define XENUSB_PIPE_TYPE_ISOC	0 +#define XENUSB_PIPE_TYPE_INT	1 +#define XENUSB_PIPE_TYPE_CTRL	2 +#define XENUSB_PIPE_TYPE_BULK	3 + +#define xenusb_pipeportnum(pipe)		((pipe) & XENUSB_PIPE_PORT_MASK) +#define xenusb_setportnum_pipe(pipe, portnum)	((pipe) | (portnum)) + +#define xenusb_pipeunlink(pipe)			((pipe) & XENUSB_PIPE_UNLINK) +#define xenusb_pipesubmit(pipe)			(!xenusb_pipeunlink(pipe)) +#define xenusb_setunlink_pipe(pipe)		((pipe) | XENUSB_PIPE_UNLINK) + +#define xenusb_pipein(pipe)			((pipe) & XENUSB_PIPE_DIR) +#define xenusb_pipeout(pipe)			(!xenusb_pipein(pipe)) + +#define xenusb_pipedevice(pipe)			\ +	(((pipe) >> XENUSB_PIPE_DEV_SHIFT) & XENUSB_PIPE_DEV_MASK) + +#define xenusb_pipeendpoint(pipe)		\ +	(((pipe) >> XENUSB_PIPE_EP_SHIFT) & XENUSB_PIPE_EP_MASK) + +#define xenusb_pipetype(pipe)			\ +	(((pipe) >> XENUSB_PIPE_TYPE_SHIFT) & XENUSB_PIPE_TYPE_MASK) +#define xenusb_pipeisoc(pipe)	(xenusb_pipetype(pipe) == XENUSB_PIPE_TYPE_ISOC) +#define xenusb_pipeint(pipe)	(xenusb_pipetype(pipe) == XENUSB_PIPE_TYPE_INT) +#define xenusb_pipectrl(pipe)	(xenusb_pipetype(pipe) == XENUSB_PIPE_TYPE_CTRL) +#define xenusb_pipebulk(pipe)	(xenusb_pipetype(pipe) == XENUSB_PIPE_TYPE_BULK) + +#define XENUSB_MAX_SEGMENTS_PER_REQUEST (16) +#define XENUSB_MAX_PORTNR		31 +#define XENUSB_RING_SIZE		4096 + +/* + * RING for transferring urbs. + */ +struct xenusb_request_segment { +	grant_ref_t gref; +	uint16_t offset; +	uint16_t length; +}; + +struct xenusb_urb_request { +	uint16_t id;			/* request id */ +	uint16_t nr_buffer_segs;	/* number of urb->transfer_buffer segments */ + +	/* basic urb parameter */ +	uint32_t pipe; +	uint16_t transfer_flags; +#define XENUSB_SHORT_NOT_OK	0x0001 +	uint16_t buffer_length; +	union { +		uint8_t ctrl[8];	/* setup_packet (Ctrl) */ + +		struct { +			uint16_t interval;	/* maximum (1024*8) in usb core */ +			uint16_t start_frame;	/* start frame */ +			uint16_t number_of_packets;	/* number of ISO packet */ +			uint16_t nr_frame_desc_segs;	/* number of iso_frame_desc segments */ +		} isoc; + +		struct { +			uint16_t interval;	/* maximum (1024*8) in usb core */ +			uint16_t pad[3]; +		} intr; + +		struct { +			uint16_t unlink_id;	/* unlink request id */ +			uint16_t pad[3]; +		} unlink; + +	} u; + +	/* urb data segments */ +	struct xenusb_request_segment seg[XENUSB_MAX_SEGMENTS_PER_REQUEST]; +}; + +struct xenusb_urb_response { +	uint16_t id;		/* request id */ +	uint16_t start_frame;	/* start frame (ISO) */ +	int32_t status;		/* status (non-ISO) */ +#define XENUSB_STATUS_OK	0 +#define XENUSB_STATUS_NODEV	(-19) +#define XENUSB_STATUS_INVAL	(-22) +#define XENUSB_STATUS_STALL	(-32) +#define XENUSB_STATUS_IOERROR	(-71) +#define XENUSB_STATUS_BABBLE	(-75) +#define XENUSB_STATUS_SHUTDOWN	(-108) +	int32_t actual_length;	/* actual transfer length */ +	int32_t error_count;	/* number of ISO errors */ +}; + +DEFINE_RING_TYPES(xenusb_urb, struct xenusb_urb_request, struct xenusb_urb_response); +#define XENUSB_URB_RING_SIZE __CONST_RING_SIZE(xenusb_urb, XENUSB_RING_SIZE) + +/* + * RING for notifying connect/disconnect events to frontend + */ +struct xenusb_conn_request { +	uint16_t id; +}; + +struct xenusb_conn_response { +	uint16_t id;		/* request id */ +	uint8_t portnum;	/* port number */ +	uint8_t speed;		/* usb_device_speed */ +#define XENUSB_SPEED_NONE	0 +#define XENUSB_SPEED_LOW	1 +#define XENUSB_SPEED_FULL	2 +#define XENUSB_SPEED_HIGH	3 +}; + +DEFINE_RING_TYPES(xenusb_conn, struct xenusb_conn_request, struct xenusb_conn_response); +#define XENUSB_CONN_RING_SIZE __CONST_RING_SIZE(xenusb_conn, XENUSB_RING_SIZE) + +#endif /* __XEN_PUBLIC_IO_USBIF_H__ */ |