Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | /* SPDX-License-Identifier: MIT */ /* * usbif.h * * USB I/O interface for Xen guest OSes. * * Copyright (C) 2009, FUJITSU LABORATORIES LTD. * Author: Noboru Iwamatsu <n_iwamatsu@jp.fujitsu.com> */ #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__ */ |