10d09e41aSPaolo Bonzini #ifndef QEMU_USB_H
20d09e41aSPaolo Bonzini #define QEMU_USB_H
30d09e41aSPaolo Bonzini
40d09e41aSPaolo Bonzini /*
50d09e41aSPaolo Bonzini * QEMU USB API
60d09e41aSPaolo Bonzini *
70d09e41aSPaolo Bonzini * Copyright (c) 2005 Fabrice Bellard
80d09e41aSPaolo Bonzini *
90d09e41aSPaolo Bonzini * Permission is hereby granted, free of charge, to any person obtaining a copy
100d09e41aSPaolo Bonzini * of this software and associated documentation files (the "Software"), to deal
110d09e41aSPaolo Bonzini * in the Software without restriction, including without limitation the rights
120d09e41aSPaolo Bonzini * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
130d09e41aSPaolo Bonzini * copies of the Software, and to permit persons to whom the Software is
140d09e41aSPaolo Bonzini * furnished to do so, subject to the following conditions:
150d09e41aSPaolo Bonzini *
160d09e41aSPaolo Bonzini * The above copyright notice and this permission notice shall be included in
170d09e41aSPaolo Bonzini * all copies or substantial portions of the Software.
180d09e41aSPaolo Bonzini *
190d09e41aSPaolo Bonzini * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
200d09e41aSPaolo Bonzini * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
210d09e41aSPaolo Bonzini * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
220d09e41aSPaolo Bonzini * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
230d09e41aSPaolo Bonzini * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
240d09e41aSPaolo Bonzini * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
250d09e41aSPaolo Bonzini * THE SOFTWARE.
260d09e41aSPaolo Bonzini */
270d09e41aSPaolo Bonzini
28d4842052SMarkus Armbruster #include "exec/memory.h"
29a27bd6c7SMarkus Armbruster #include "hw/qdev-core.h"
30daf015efSMarkus Armbruster #include "qemu/iov.h"
310d09e41aSPaolo Bonzini #include "qemu/queue.h"
32db1015e9SEduardo Habkost #include "qom/object.h"
33*726c6099SPaolo Bonzini #include "qapi/error.h"
340d09e41aSPaolo Bonzini
350d09e41aSPaolo Bonzini /* Constants related to the USB / PCI interaction */
360d09e41aSPaolo Bonzini #define USB_SBRN 0x60 /* Serial Bus Release Number Register */
370d09e41aSPaolo Bonzini #define USB_RELEASE_1 0x10 /* USB 1.0 */
380d09e41aSPaolo Bonzini #define USB_RELEASE_2 0x20 /* USB 2.0 */
390d09e41aSPaolo Bonzini #define USB_RELEASE_3 0x30 /* USB 3.0 */
400d09e41aSPaolo Bonzini
410d09e41aSPaolo Bonzini #define USB_TOKEN_SETUP 0x2d
420d09e41aSPaolo Bonzini #define USB_TOKEN_IN 0x69 /* device -> host */
430d09e41aSPaolo Bonzini #define USB_TOKEN_OUT 0xe1 /* host -> device */
440d09e41aSPaolo Bonzini
450d09e41aSPaolo Bonzini #define USB_RET_SUCCESS (0)
460d09e41aSPaolo Bonzini #define USB_RET_NODEV (-1)
470d09e41aSPaolo Bonzini #define USB_RET_NAK (-2)
480d09e41aSPaolo Bonzini #define USB_RET_STALL (-3)
490d09e41aSPaolo Bonzini #define USB_RET_BABBLE (-4)
500d09e41aSPaolo Bonzini #define USB_RET_IOERROR (-5)
510d09e41aSPaolo Bonzini #define USB_RET_ASYNC (-6)
520d09e41aSPaolo Bonzini #define USB_RET_ADD_TO_QUEUE (-7)
530d09e41aSPaolo Bonzini #define USB_RET_REMOVE_FROM_QUEUE (-8)
540d09e41aSPaolo Bonzini
550d09e41aSPaolo Bonzini #define USB_SPEED_LOW 0
560d09e41aSPaolo Bonzini #define USB_SPEED_FULL 1
570d09e41aSPaolo Bonzini #define USB_SPEED_HIGH 2
580d09e41aSPaolo Bonzini #define USB_SPEED_SUPER 3
590d09e41aSPaolo Bonzini
600d09e41aSPaolo Bonzini #define USB_SPEED_MASK_LOW (1 << USB_SPEED_LOW)
610d09e41aSPaolo Bonzini #define USB_SPEED_MASK_FULL (1 << USB_SPEED_FULL)
620d09e41aSPaolo Bonzini #define USB_SPEED_MASK_HIGH (1 << USB_SPEED_HIGH)
630d09e41aSPaolo Bonzini #define USB_SPEED_MASK_SUPER (1 << USB_SPEED_SUPER)
640d09e41aSPaolo Bonzini
650d09e41aSPaolo Bonzini #define USB_STATE_NOTATTACHED 0
660d09e41aSPaolo Bonzini #define USB_STATE_ATTACHED 1
670d09e41aSPaolo Bonzini //#define USB_STATE_POWERED 2
680d09e41aSPaolo Bonzini #define USB_STATE_DEFAULT 3
690d09e41aSPaolo Bonzini //#define USB_STATE_ADDRESS 4
700d09e41aSPaolo Bonzini //#define USB_STATE_CONFIGURED 5
710d09e41aSPaolo Bonzini #define USB_STATE_SUSPENDED 6
720d09e41aSPaolo Bonzini
730d09e41aSPaolo Bonzini #define USB_CLASS_AUDIO 1
740d09e41aSPaolo Bonzini #define USB_CLASS_COMM 2
750d09e41aSPaolo Bonzini #define USB_CLASS_HID 3
760d09e41aSPaolo Bonzini #define USB_CLASS_PHYSICAL 5
770d09e41aSPaolo Bonzini #define USB_CLASS_STILL_IMAGE 6
780d09e41aSPaolo Bonzini #define USB_CLASS_PRINTER 7
790d09e41aSPaolo Bonzini #define USB_CLASS_MASS_STORAGE 8
800d09e41aSPaolo Bonzini #define USB_CLASS_HUB 9
810d09e41aSPaolo Bonzini #define USB_CLASS_CDC_DATA 0x0a
820d09e41aSPaolo Bonzini #define USB_CLASS_CSCID 0x0b
830d09e41aSPaolo Bonzini #define USB_CLASS_CONTENT_SEC 0x0d
840d09e41aSPaolo Bonzini #define USB_CLASS_APP_SPEC 0xfe
850d09e41aSPaolo Bonzini #define USB_CLASS_VENDOR_SPEC 0xff
860d09e41aSPaolo Bonzini
870d09e41aSPaolo Bonzini #define USB_SUBCLASS_UNDEFINED 0
880d09e41aSPaolo Bonzini #define USB_SUBCLASS_AUDIO_CONTROL 1
890d09e41aSPaolo Bonzini #define USB_SUBCLASS_AUDIO_STREAMING 2
900d09e41aSPaolo Bonzini #define USB_SUBCLASS_AUDIO_MIDISTREAMING 3
910d09e41aSPaolo Bonzini
920d09e41aSPaolo Bonzini #define USB_DIR_OUT 0
930d09e41aSPaolo Bonzini #define USB_DIR_IN 0x80
940d09e41aSPaolo Bonzini
950d09e41aSPaolo Bonzini #define USB_TYPE_MASK (0x03 << 5)
960d09e41aSPaolo Bonzini #define USB_TYPE_STANDARD (0x00 << 5)
970d09e41aSPaolo Bonzini #define USB_TYPE_CLASS (0x01 << 5)
980d09e41aSPaolo Bonzini #define USB_TYPE_VENDOR (0x02 << 5)
990d09e41aSPaolo Bonzini #define USB_TYPE_RESERVED (0x03 << 5)
1000d09e41aSPaolo Bonzini
1010d09e41aSPaolo Bonzini #define USB_RECIP_MASK 0x1f
1020d09e41aSPaolo Bonzini #define USB_RECIP_DEVICE 0x00
1030d09e41aSPaolo Bonzini #define USB_RECIP_INTERFACE 0x01
1040d09e41aSPaolo Bonzini #define USB_RECIP_ENDPOINT 0x02
1050d09e41aSPaolo Bonzini #define USB_RECIP_OTHER 0x03
1060d09e41aSPaolo Bonzini
1070d09e41aSPaolo Bonzini #define DeviceRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
1080d09e41aSPaolo Bonzini #define DeviceOutRequest ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
1092b81ba53SGerd Hoffmann #define VendorDeviceRequest ((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
1102b81ba53SGerd Hoffmann #define VendorDeviceOutRequest \
1112b81ba53SGerd Hoffmann ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
1122b81ba53SGerd Hoffmann
1130d09e41aSPaolo Bonzini #define InterfaceRequest \
1140d09e41aSPaolo Bonzini ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
1150d09e41aSPaolo Bonzini #define InterfaceOutRequest \
1160d09e41aSPaolo Bonzini ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
1170d09e41aSPaolo Bonzini #define ClassInterfaceRequest \
1180d09e41aSPaolo Bonzini ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8)
1190d09e41aSPaolo Bonzini #define ClassInterfaceOutRequest \
1200d09e41aSPaolo Bonzini ((USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8)
1212b81ba53SGerd Hoffmann #define VendorInterfaceRequest \
1222b81ba53SGerd Hoffmann ((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE)<<8)
1232b81ba53SGerd Hoffmann #define VendorInterfaceOutRequest \
1242b81ba53SGerd Hoffmann ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE)<<8)
1252b81ba53SGerd Hoffmann
1262b81ba53SGerd Hoffmann #define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
1272b81ba53SGerd Hoffmann #define EndpointOutRequest \
1282b81ba53SGerd Hoffmann ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
1290d09e41aSPaolo Bonzini
1300d09e41aSPaolo Bonzini #define USB_REQ_GET_STATUS 0x00
1310d09e41aSPaolo Bonzini #define USB_REQ_CLEAR_FEATURE 0x01
1320d09e41aSPaolo Bonzini #define USB_REQ_SET_FEATURE 0x03
1330d09e41aSPaolo Bonzini #define USB_REQ_SET_ADDRESS 0x05
1340d09e41aSPaolo Bonzini #define USB_REQ_GET_DESCRIPTOR 0x06
1350d09e41aSPaolo Bonzini #define USB_REQ_SET_DESCRIPTOR 0x07
1360d09e41aSPaolo Bonzini #define USB_REQ_GET_CONFIGURATION 0x08
1370d09e41aSPaolo Bonzini #define USB_REQ_SET_CONFIGURATION 0x09
1380d09e41aSPaolo Bonzini #define USB_REQ_GET_INTERFACE 0x0A
1390d09e41aSPaolo Bonzini #define USB_REQ_SET_INTERFACE 0x0B
1400d09e41aSPaolo Bonzini #define USB_REQ_SYNCH_FRAME 0x0C
141811ad5d8SGerd Hoffmann #define USB_REQ_SET_SEL 0x30
142811ad5d8SGerd Hoffmann #define USB_REQ_SET_ISOCH_DELAY 0x31
1430d09e41aSPaolo Bonzini
1440d09e41aSPaolo Bonzini #define USB_DEVICE_SELF_POWERED 0
1450d09e41aSPaolo Bonzini #define USB_DEVICE_REMOTE_WAKEUP 1
1460d09e41aSPaolo Bonzini
1470d09e41aSPaolo Bonzini #define USB_DT_DEVICE 0x01
1480d09e41aSPaolo Bonzini #define USB_DT_CONFIG 0x02
1490d09e41aSPaolo Bonzini #define USB_DT_STRING 0x03
1500d09e41aSPaolo Bonzini #define USB_DT_INTERFACE 0x04
1510d09e41aSPaolo Bonzini #define USB_DT_ENDPOINT 0x05
1520d09e41aSPaolo Bonzini #define USB_DT_DEVICE_QUALIFIER 0x06
1530d09e41aSPaolo Bonzini #define USB_DT_OTHER_SPEED_CONFIG 0x07
1540d09e41aSPaolo Bonzini #define USB_DT_DEBUG 0x0A
1550d09e41aSPaolo Bonzini #define USB_DT_INTERFACE_ASSOC 0x0B
1560d09e41aSPaolo Bonzini #define USB_DT_BOS 0x0F
1570d09e41aSPaolo Bonzini #define USB_DT_DEVICE_CAPABILITY 0x10
1580d09e41aSPaolo Bonzini #define USB_DT_CS_INTERFACE 0x24
1590d09e41aSPaolo Bonzini #define USB_DT_CS_ENDPOINT 0x25
1600d09e41aSPaolo Bonzini #define USB_DT_ENDPOINT_COMPANION 0x30
1610d09e41aSPaolo Bonzini
1620d09e41aSPaolo Bonzini #define USB_DEV_CAP_WIRELESS 0x01
1630d09e41aSPaolo Bonzini #define USB_DEV_CAP_USB2_EXT 0x02
1640d09e41aSPaolo Bonzini #define USB_DEV_CAP_SUPERSPEED 0x03
1650d09e41aSPaolo Bonzini
166bd93976aSPantelis Koukousoulas #define USB_CFG_ATT_ONE (1 << 7) /* should always be set */
167bd93976aSPantelis Koukousoulas #define USB_CFG_ATT_SELFPOWER (1 << 6)
168bd93976aSPantelis Koukousoulas #define USB_CFG_ATT_WAKEUP (1 << 5)
169bd93976aSPantelis Koukousoulas #define USB_CFG_ATT_BATTERY (1 << 4)
170bd93976aSPantelis Koukousoulas
1710d09e41aSPaolo Bonzini #define USB_ENDPOINT_XFER_CONTROL 0
1720d09e41aSPaolo Bonzini #define USB_ENDPOINT_XFER_ISOC 1
1730d09e41aSPaolo Bonzini #define USB_ENDPOINT_XFER_BULK 2
1740d09e41aSPaolo Bonzini #define USB_ENDPOINT_XFER_INT 3
1750d09e41aSPaolo Bonzini #define USB_ENDPOINT_XFER_INVALID 255
1760d09e41aSPaolo Bonzini
1770d09e41aSPaolo Bonzini #define USB_INTERFACE_INVALID 255
1780d09e41aSPaolo Bonzini
1790d09e41aSPaolo Bonzini typedef struct USBBusOps USBBusOps;
1800d09e41aSPaolo Bonzini typedef struct USBPort USBPort;
1810d09e41aSPaolo Bonzini typedef struct USBDevice USBDevice;
1820d09e41aSPaolo Bonzini typedef struct USBPacket USBPacket;
1830d09e41aSPaolo Bonzini typedef struct USBCombinedPacket USBCombinedPacket;
1840d09e41aSPaolo Bonzini typedef struct USBEndpoint USBEndpoint;
1850d09e41aSPaolo Bonzini
1860d09e41aSPaolo Bonzini typedef struct USBDesc USBDesc;
1870d09e41aSPaolo Bonzini typedef struct USBDescID USBDescID;
1880d09e41aSPaolo Bonzini typedef struct USBDescDevice USBDescDevice;
1890d09e41aSPaolo Bonzini typedef struct USBDescConfig USBDescConfig;
1900d09e41aSPaolo Bonzini typedef struct USBDescIfaceAssoc USBDescIfaceAssoc;
1910d09e41aSPaolo Bonzini typedef struct USBDescIface USBDescIface;
1920d09e41aSPaolo Bonzini typedef struct USBDescEndpoint USBDescEndpoint;
1930d09e41aSPaolo Bonzini typedef struct USBDescOther USBDescOther;
1940d09e41aSPaolo Bonzini typedef struct USBDescString USBDescString;
1955319dc7bSGerd Hoffmann typedef struct USBDescMSOS USBDescMSOS;
1960d09e41aSPaolo Bonzini
1970d09e41aSPaolo Bonzini struct USBDescString {
1980d09e41aSPaolo Bonzini uint8_t index;
1990d09e41aSPaolo Bonzini char *str;
2000d09e41aSPaolo Bonzini QLIST_ENTRY(USBDescString) next;
2010d09e41aSPaolo Bonzini };
2020d09e41aSPaolo Bonzini
2030d09e41aSPaolo Bonzini #define USB_MAX_ENDPOINTS 15
2040d09e41aSPaolo Bonzini #define USB_MAX_INTERFACES 16
2050d09e41aSPaolo Bonzini
2060d09e41aSPaolo Bonzini struct USBEndpoint {
2070d09e41aSPaolo Bonzini uint8_t nr;
2080d09e41aSPaolo Bonzini uint8_t pid;
2090d09e41aSPaolo Bonzini uint8_t type;
2100d09e41aSPaolo Bonzini uint8_t ifnum;
2110d09e41aSPaolo Bonzini int max_packet_size;
21204b300f8SHans de Goede int max_streams;
2130d09e41aSPaolo Bonzini bool pipeline;
2140d09e41aSPaolo Bonzini bool halted;
2150d09e41aSPaolo Bonzini USBDevice *dev;
2160d09e41aSPaolo Bonzini QTAILQ_HEAD(, USBPacket) queue;
2170d09e41aSPaolo Bonzini };
2180d09e41aSPaolo Bonzini
2190d09e41aSPaolo Bonzini enum USBDeviceFlags {
2200d09e41aSPaolo Bonzini USB_DEV_FLAG_IS_HOST,
2215319dc7bSGerd Hoffmann USB_DEV_FLAG_MSOS_DESC_ENABLE,
2225319dc7bSGerd Hoffmann USB_DEV_FLAG_MSOS_DESC_IN_USE,
223b7b2a60bSGerd Hoffmann USB_DEV_FLAG_IS_SCSI_STORAGE,
2240d09e41aSPaolo Bonzini };
2250d09e41aSPaolo Bonzini
2260d09e41aSPaolo Bonzini /* definition of a USB device */
2270d09e41aSPaolo Bonzini struct USBDevice {
2280d09e41aSPaolo Bonzini DeviceState qdev;
2290d09e41aSPaolo Bonzini USBPort *port;
2300d09e41aSPaolo Bonzini char *port_path;
23171938a09SGerd Hoffmann char *serial;
2320d09e41aSPaolo Bonzini void *opaque;
2330d09e41aSPaolo Bonzini uint32_t flags;
2340d09e41aSPaolo Bonzini
2350f6dba14SGerd Hoffmann char *pcap_filename;
2360f6dba14SGerd Hoffmann FILE *pcap;
2370f6dba14SGerd Hoffmann
2380d09e41aSPaolo Bonzini /* Actual connected speed */
2390d09e41aSPaolo Bonzini int speed;
2400d09e41aSPaolo Bonzini /* Supported speeds, not in info because it may be variable (hostdevs) */
2410d09e41aSPaolo Bonzini int speedmask;
2420d09e41aSPaolo Bonzini uint8_t addr;
2430d09e41aSPaolo Bonzini char product_desc[32];
2440d09e41aSPaolo Bonzini int auto_attach;
245eb19d2b9SGerd Hoffmann bool attached;
2460d09e41aSPaolo Bonzini
2470d09e41aSPaolo Bonzini int32_t state;
2480d09e41aSPaolo Bonzini uint8_t setup_buf[8];
2490d09e41aSPaolo Bonzini uint8_t data_buf[4096];
2500d09e41aSPaolo Bonzini int32_t remote_wakeup;
2510d09e41aSPaolo Bonzini int32_t setup_state;
2520d09e41aSPaolo Bonzini int32_t setup_len;
2530d09e41aSPaolo Bonzini int32_t setup_index;
2540d09e41aSPaolo Bonzini
2550d09e41aSPaolo Bonzini USBEndpoint ep_ctl;
2560d09e41aSPaolo Bonzini USBEndpoint ep_in[USB_MAX_ENDPOINTS];
2570d09e41aSPaolo Bonzini USBEndpoint ep_out[USB_MAX_ENDPOINTS];
2580d09e41aSPaolo Bonzini
2590d09e41aSPaolo Bonzini QLIST_HEAD(, USBDescString) strings;
2600d09e41aSPaolo Bonzini const USBDesc *usb_desc; /* Overrides class usb_desc if not NULL */
2610d09e41aSPaolo Bonzini const USBDescDevice *device;
2620d09e41aSPaolo Bonzini
2630d09e41aSPaolo Bonzini int configuration;
2640d09e41aSPaolo Bonzini int ninterfaces;
2650d09e41aSPaolo Bonzini int altsetting[USB_MAX_INTERFACES];
2660d09e41aSPaolo Bonzini const USBDescConfig *config;
2670d09e41aSPaolo Bonzini const USBDescIface *ifaces[USB_MAX_INTERFACES];
2680d09e41aSPaolo Bonzini };
2690d09e41aSPaolo Bonzini
2700d09e41aSPaolo Bonzini #define TYPE_USB_DEVICE "usb-device"
271a489d195SEduardo Habkost OBJECT_DECLARE_TYPE(USBDevice, USBDeviceClass, USB_DEVICE)
2720d09e41aSPaolo Bonzini
2737d553f27SGonglei typedef void (*USBDeviceRealize)(USBDevice *dev, Error **errp);
274b69c3c21SMarkus Armbruster typedef void (*USBDeviceUnrealize)(USBDevice *dev);
2757d553f27SGonglei
276db1015e9SEduardo Habkost struct USBDeviceClass {
2770d09e41aSPaolo Bonzini DeviceClass parent_class;
2780d09e41aSPaolo Bonzini
2797d553f27SGonglei USBDeviceRealize realize;
2807d553f27SGonglei USBDeviceUnrealize unrealize;
2817d553f27SGonglei
2820d09e41aSPaolo Bonzini /*
2830d09e41aSPaolo Bonzini * Walk (enabled) downstream ports, check for a matching device.
2840d09e41aSPaolo Bonzini * Only hubs implement this.
2850d09e41aSPaolo Bonzini */
2860d09e41aSPaolo Bonzini USBDevice *(*find_device)(USBDevice *dev, uint8_t addr);
2870d09e41aSPaolo Bonzini
2880d09e41aSPaolo Bonzini /*
2890d09e41aSPaolo Bonzini * Called when a packet is canceled.
2900d09e41aSPaolo Bonzini */
2910d09e41aSPaolo Bonzini void (*cancel_packet)(USBDevice *dev, USBPacket *p);
2920d09e41aSPaolo Bonzini
2930d09e41aSPaolo Bonzini /*
2940d09e41aSPaolo Bonzini * Attach the device
2950d09e41aSPaolo Bonzini */
2960d09e41aSPaolo Bonzini void (*handle_attach)(USBDevice *dev);
2970d09e41aSPaolo Bonzini
2980d09e41aSPaolo Bonzini /*
2990d09e41aSPaolo Bonzini * Reset the device
3000d09e41aSPaolo Bonzini */
3010d09e41aSPaolo Bonzini void (*handle_reset)(USBDevice *dev);
3020d09e41aSPaolo Bonzini
3030d09e41aSPaolo Bonzini /*
3040d09e41aSPaolo Bonzini * Process control request.
3050d09e41aSPaolo Bonzini * Called from handle_packet().
3060d09e41aSPaolo Bonzini *
3070d09e41aSPaolo Bonzini * Status gets stored in p->status, and if p->status == USB_RET_SUCCESS
3080d09e41aSPaolo Bonzini * then the number of bytes transferred is stored in p->actual_length
3090d09e41aSPaolo Bonzini */
3100d09e41aSPaolo Bonzini void (*handle_control)(USBDevice *dev, USBPacket *p, int request, int value,
3110d09e41aSPaolo Bonzini int index, int length, uint8_t *data);
3120d09e41aSPaolo Bonzini
3130d09e41aSPaolo Bonzini /*
3140d09e41aSPaolo Bonzini * Process data transfers (both BULK and ISOC).
3150d09e41aSPaolo Bonzini * Called from handle_packet().
3160d09e41aSPaolo Bonzini *
3170d09e41aSPaolo Bonzini * Status gets stored in p->status, and if p->status == USB_RET_SUCCESS
3180d09e41aSPaolo Bonzini * then the number of bytes transferred is stored in p->actual_length
3190d09e41aSPaolo Bonzini */
3200d09e41aSPaolo Bonzini void (*handle_data)(USBDevice *dev, USBPacket *p);
3210d09e41aSPaolo Bonzini
3220d09e41aSPaolo Bonzini void (*set_interface)(USBDevice *dev, int interface,
3230d09e41aSPaolo Bonzini int alt_old, int alt_new);
3240d09e41aSPaolo Bonzini
3250d09e41aSPaolo Bonzini /*
3260d09e41aSPaolo Bonzini * Called when the hcd is done queuing packets for an endpoint, only
3270d09e41aSPaolo Bonzini * necessary for devices which can return USB_RET_ADD_TO_QUEUE.
3280d09e41aSPaolo Bonzini */
3290d09e41aSPaolo Bonzini void (*flush_ep_queue)(USBDevice *dev, USBEndpoint *ep);
3300d09e41aSPaolo Bonzini
3310d09e41aSPaolo Bonzini /*
3320d09e41aSPaolo Bonzini * Called by the hcd to let the device know the queue for an endpoint
3330d09e41aSPaolo Bonzini * has been unlinked / stopped. Optional may be NULL.
3340d09e41aSPaolo Bonzini */
3350d09e41aSPaolo Bonzini void (*ep_stopped)(USBDevice *dev, USBEndpoint *ep);
3360d09e41aSPaolo Bonzini
3373b444eadSHans de Goede /*
3383b444eadSHans de Goede * Called by the hcd to alloc / free streams on a bulk endpoint.
3393b444eadSHans de Goede * Optional may be NULL.
3403b444eadSHans de Goede */
3413b444eadSHans de Goede int (*alloc_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps,
3423b444eadSHans de Goede int streams);
3433b444eadSHans de Goede void (*free_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps);
3443b444eadSHans de Goede
3450d09e41aSPaolo Bonzini const char *product_desc;
3460d09e41aSPaolo Bonzini const USBDesc *usb_desc;
3471e351dc3SGerd Hoffmann bool attached_settable;
348db1015e9SEduardo Habkost };
3490d09e41aSPaolo Bonzini
3500d09e41aSPaolo Bonzini typedef struct USBPortOps {
3510d09e41aSPaolo Bonzini void (*attach)(USBPort *port);
3520d09e41aSPaolo Bonzini void (*detach)(USBPort *port);
3530d09e41aSPaolo Bonzini /*
3540d09e41aSPaolo Bonzini * This gets called when a device downstream from the device attached to
3550d09e41aSPaolo Bonzini * the port (iow attached through a hub) gets detached.
3560d09e41aSPaolo Bonzini */
3570d09e41aSPaolo Bonzini void (*child_detach)(USBPort *port, USBDevice *child);
3580d09e41aSPaolo Bonzini void (*wakeup)(USBPort *port);
3590d09e41aSPaolo Bonzini /*
3600d09e41aSPaolo Bonzini * Note that port->dev will be different then the device from which
3610d09e41aSPaolo Bonzini * the packet originated when a hub is involved.
3620d09e41aSPaolo Bonzini */
3630d09e41aSPaolo Bonzini void (*complete)(USBPort *port, USBPacket *p);
3640d09e41aSPaolo Bonzini } USBPortOps;
3650d09e41aSPaolo Bonzini
3660d09e41aSPaolo Bonzini /* USB port on which a device can be connected */
3670d09e41aSPaolo Bonzini struct USBPort {
3680d09e41aSPaolo Bonzini USBDevice *dev;
3690d09e41aSPaolo Bonzini int speedmask;
37047b5264eSAnthony Liguori int hubcount;
3710d09e41aSPaolo Bonzini char path[16];
3720d09e41aSPaolo Bonzini USBPortOps *ops;
3730d09e41aSPaolo Bonzini void *opaque;
3740d09e41aSPaolo Bonzini int index; /* internal port index, may be used with the opaque */
3750d09e41aSPaolo Bonzini QTAILQ_ENTRY(USBPort) next;
3760d09e41aSPaolo Bonzini };
3770d09e41aSPaolo Bonzini
3780d09e41aSPaolo Bonzini typedef void USBCallback(USBPacket * packet, void *opaque);
3790d09e41aSPaolo Bonzini
3800d09e41aSPaolo Bonzini typedef enum USBPacketState {
3810d09e41aSPaolo Bonzini USB_PACKET_UNDEFINED = 0,
3820d09e41aSPaolo Bonzini USB_PACKET_SETUP,
3830d09e41aSPaolo Bonzini USB_PACKET_QUEUED,
3840d09e41aSPaolo Bonzini USB_PACKET_ASYNC,
3850d09e41aSPaolo Bonzini USB_PACKET_COMPLETE,
3860d09e41aSPaolo Bonzini USB_PACKET_CANCELED,
3870d09e41aSPaolo Bonzini } USBPacketState;
3880d09e41aSPaolo Bonzini
3890d09e41aSPaolo Bonzini /* Structure used to hold information about an active USB packet. */
3900d09e41aSPaolo Bonzini struct USBPacket {
3910d09e41aSPaolo Bonzini /* Data fields for use by the driver. */
3920d09e41aSPaolo Bonzini int pid;
3930d09e41aSPaolo Bonzini uint64_t id;
3940d09e41aSPaolo Bonzini USBEndpoint *ep;
3950d09e41aSPaolo Bonzini unsigned int stream;
3960d09e41aSPaolo Bonzini QEMUIOVector iov;
3970d09e41aSPaolo Bonzini uint64_t parameter; /* control transfers */
3980d09e41aSPaolo Bonzini bool short_not_ok;
3990d09e41aSPaolo Bonzini bool int_req;
4000d09e41aSPaolo Bonzini int status; /* USB_RET_* status code */
4010d09e41aSPaolo Bonzini int actual_length; /* Number of bytes actually transferred */
4020d09e41aSPaolo Bonzini /* Internal use by the USB layer. */
4030d09e41aSPaolo Bonzini USBPacketState state;
4040d09e41aSPaolo Bonzini USBCombinedPacket *combined;
4050d09e41aSPaolo Bonzini QTAILQ_ENTRY(USBPacket) queue;
4060d09e41aSPaolo Bonzini QTAILQ_ENTRY(USBPacket) combined_entry;
4070d09e41aSPaolo Bonzini };
4080d09e41aSPaolo Bonzini
4090d09e41aSPaolo Bonzini struct USBCombinedPacket {
4100d09e41aSPaolo Bonzini USBPacket *first;
411eae3eb3eSPaolo Bonzini QTAILQ_HEAD(, USBPacket) packets;
4120d09e41aSPaolo Bonzini QEMUIOVector iov;
4130d09e41aSPaolo Bonzini };
4140d09e41aSPaolo Bonzini
4150d09e41aSPaolo Bonzini void usb_packet_init(USBPacket *p);
4160d09e41aSPaolo Bonzini void usb_packet_set_state(USBPacket *p, USBPacketState state);
4170d09e41aSPaolo Bonzini void usb_packet_check_state(USBPacket *p, USBPacketState expected);
4180d09e41aSPaolo Bonzini void usb_packet_setup(USBPacket *p, int pid,
4190d09e41aSPaolo Bonzini USBEndpoint *ep, unsigned int stream,
4200d09e41aSPaolo Bonzini uint64_t id, bool short_not_ok, bool int_req);
4210d09e41aSPaolo Bonzini void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len);
4220d09e41aSPaolo Bonzini int usb_packet_map(USBPacket *p, QEMUSGList *sgl);
4230d09e41aSPaolo Bonzini void usb_packet_unmap(USBPacket *p, QEMUSGList *sgl);
4240d09e41aSPaolo Bonzini void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes);
4250d09e41aSPaolo Bonzini void usb_packet_skip(USBPacket *p, size_t bytes);
4260d09e41aSPaolo Bonzini size_t usb_packet_size(USBPacket *p);
4270d09e41aSPaolo Bonzini void usb_packet_cleanup(USBPacket *p);
4280d09e41aSPaolo Bonzini
usb_packet_is_inflight(USBPacket * p)4290d09e41aSPaolo Bonzini static inline bool usb_packet_is_inflight(USBPacket *p)
4300d09e41aSPaolo Bonzini {
4310d09e41aSPaolo Bonzini return (p->state == USB_PACKET_QUEUED ||
4320d09e41aSPaolo Bonzini p->state == USB_PACKET_ASYNC);
4330d09e41aSPaolo Bonzini }
4340d09e41aSPaolo Bonzini
4350d09e41aSPaolo Bonzini USBDevice *usb_find_device(USBPort *port, uint8_t addr);
4360d09e41aSPaolo Bonzini
4370d09e41aSPaolo Bonzini void usb_handle_packet(USBDevice *dev, USBPacket *p);
4380d09e41aSPaolo Bonzini void usb_packet_complete(USBDevice *dev, USBPacket *p);
4390d09e41aSPaolo Bonzini void usb_packet_complete_one(USBDevice *dev, USBPacket *p);
4400d09e41aSPaolo Bonzini void usb_cancel_packet(USBPacket * p);
4410d09e41aSPaolo Bonzini
4420d09e41aSPaolo Bonzini void usb_ep_init(USBDevice *dev);
4430d09e41aSPaolo Bonzini void usb_ep_reset(USBDevice *dev);
4440d09e41aSPaolo Bonzini void usb_ep_dump(USBDevice *dev);
4450d09e41aSPaolo Bonzini struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep);
4460d09e41aSPaolo Bonzini uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep);
4470d09e41aSPaolo Bonzini void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type);
4480d09e41aSPaolo Bonzini void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum);
4490d09e41aSPaolo Bonzini void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
4500d09e41aSPaolo Bonzini uint16_t raw);
45104b300f8SHans de Goede void usb_ep_set_max_streams(USBDevice *dev, int pid, int ep, uint8_t raw);
4520d09e41aSPaolo Bonzini void usb_ep_set_halted(USBDevice *dev, int pid, int ep, bool halted);
4530d09e41aSPaolo Bonzini USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep,
4540d09e41aSPaolo Bonzini uint64_t id);
4550d09e41aSPaolo Bonzini
4560d09e41aSPaolo Bonzini void usb_ep_combine_input_packets(USBEndpoint *ep);
4570d09e41aSPaolo Bonzini void usb_combined_input_packet_complete(USBDevice *dev, USBPacket *p);
4580d09e41aSPaolo Bonzini void usb_combined_packet_cancel(USBDevice *dev, USBPacket *p);
4590d09e41aSPaolo Bonzini
460b791c3b3SGerd Hoffmann void usb_pick_speed(USBPort *port);
4610d09e41aSPaolo Bonzini void usb_attach(USBPort *port);
4620d09e41aSPaolo Bonzini void usb_detach(USBPort *port);
4630d09e41aSPaolo Bonzini void usb_port_reset(USBPort *port);
4640d09e41aSPaolo Bonzini void usb_device_reset(USBDevice *dev);
4650d09e41aSPaolo Bonzini void usb_wakeup(USBEndpoint *ep, unsigned int stream);
4660d09e41aSPaolo Bonzini void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p);
4670d09e41aSPaolo Bonzini
4680d09e41aSPaolo Bonzini /* usb-linux.c */
4691ce6be24SMarkus Armbruster void hmp_info_usbhost(Monitor *mon, const QDict *qdict);
4700d09e41aSPaolo Bonzini
4710d09e41aSPaolo Bonzini /* usb ports of the VM */
4720d09e41aSPaolo Bonzini
4730d09e41aSPaolo Bonzini #define VM_USB_HUB_SIZE 8
4740d09e41aSPaolo Bonzini
4750d09e41aSPaolo Bonzini /* usb-bus.c */
4760d09e41aSPaolo Bonzini
4770d09e41aSPaolo Bonzini #define TYPE_USB_BUS "usb-bus"
4788063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(USBBus, USB_BUS)
4790d09e41aSPaolo Bonzini
4800d09e41aSPaolo Bonzini struct USBBus {
4810d09e41aSPaolo Bonzini BusState qbus;
4820d09e41aSPaolo Bonzini USBBusOps *ops;
4830d09e41aSPaolo Bonzini int busnr;
4840d09e41aSPaolo Bonzini int nfree;
4850d09e41aSPaolo Bonzini int nused;
4860d09e41aSPaolo Bonzini QTAILQ_HEAD(, USBPort) free;
4870d09e41aSPaolo Bonzini QTAILQ_HEAD(, USBPort) used;
4880d09e41aSPaolo Bonzini QTAILQ_ENTRY(USBBus) next;
4890d09e41aSPaolo Bonzini };
4900d09e41aSPaolo Bonzini
4910d09e41aSPaolo Bonzini struct USBBusOps {
492f4bbaaf5SMarkus Armbruster void (*register_companion)(USBBus *bus, USBPort *ports[],
493f4bbaaf5SMarkus Armbruster uint32_t portcount, uint32_t firstport,
494f4bbaaf5SMarkus Armbruster Error **errp);
4950d09e41aSPaolo Bonzini void (*wakeup_endpoint)(USBBus *bus, USBEndpoint *ep, unsigned int stream);
4960d09e41aSPaolo Bonzini };
4970d09e41aSPaolo Bonzini
498c889b3a5SAndreas Färber void usb_bus_new(USBBus *bus, size_t bus_size,
499c889b3a5SAndreas Färber USBBusOps *ops, DeviceState *host);
500e5a9beceSGonglei void usb_bus_release(USBBus *bus);
5010d09e41aSPaolo Bonzini void usb_legacy_register(const char *typename, const char *usbdevice_name,
502405cf80cSPaolo Bonzini USBDevice *(*usbdevice_init)(void));
5030d09e41aSPaolo Bonzini USBDevice *usbdevice_create(const char *cmdline);
5040d09e41aSPaolo Bonzini void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
5050d09e41aSPaolo Bonzini USBPortOps *ops, int speedmask);
506f4bbaaf5SMarkus Armbruster void usb_register_companion(const char *masterbus, USBPort *ports[],
5070d09e41aSPaolo Bonzini uint32_t portcount, uint32_t firstport,
508f4bbaaf5SMarkus Armbruster void *opaque, USBPortOps *ops, int speedmask,
509f4bbaaf5SMarkus Armbruster Error **errp);
5100d09e41aSPaolo Bonzini void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr);
5110d09e41aSPaolo Bonzini void usb_unregister_port(USBBus *bus, USBPort *port);
5127d553f27SGonglei void usb_claim_port(USBDevice *dev, Error **errp);
5130d09e41aSPaolo Bonzini void usb_release_port(USBDevice *dev);
5147d553f27SGonglei void usb_device_attach(USBDevice *dev, Error **errp);
5150d09e41aSPaolo Bonzini int usb_device_detach(USBDevice *dev);
516594a5360SGonglei void usb_check_attach(USBDevice *dev, Error **errp);
5170d09e41aSPaolo Bonzini
usb_bus_from_device(USBDevice * d)5180d09e41aSPaolo Bonzini static inline USBBus *usb_bus_from_device(USBDevice *d)
5190d09e41aSPaolo Bonzini {
5200d09e41aSPaolo Bonzini return DO_UPCAST(USBBus, qbus, d->qdev.parent_bus);
5210d09e41aSPaolo Bonzini }
5220d09e41aSPaolo Bonzini
5230d09e41aSPaolo Bonzini extern const VMStateDescription vmstate_usb_device;
5240d09e41aSPaolo Bonzini
5250d09e41aSPaolo Bonzini #define VMSTATE_USB_DEVICE(_field, _state) { \
5260d09e41aSPaolo Bonzini .name = (stringify(_field)), \
5270d09e41aSPaolo Bonzini .size = sizeof(USBDevice), \
5280d09e41aSPaolo Bonzini .vmsd = &vmstate_usb_device, \
5290d09e41aSPaolo Bonzini .flags = VMS_STRUCT, \
5300d09e41aSPaolo Bonzini .offset = vmstate_offset_value(_state, _field, USBDevice), \
5310d09e41aSPaolo Bonzini }
5320d09e41aSPaolo Bonzini
5330d09e41aSPaolo Bonzini USBDevice *usb_device_find_device(USBDevice *dev, uint8_t addr);
5340d09e41aSPaolo Bonzini
5350d09e41aSPaolo Bonzini void usb_device_cancel_packet(USBDevice *dev, USBPacket *p);
5360d09e41aSPaolo Bonzini
5370d09e41aSPaolo Bonzini void usb_device_handle_attach(USBDevice *dev);
5380d09e41aSPaolo Bonzini
5390d09e41aSPaolo Bonzini void usb_device_handle_reset(USBDevice *dev);
5400d09e41aSPaolo Bonzini
5410d09e41aSPaolo Bonzini void usb_device_handle_control(USBDevice *dev, USBPacket *p, int request,
5420d09e41aSPaolo Bonzini int val, int index, int length, uint8_t *data);
5430d09e41aSPaolo Bonzini
5440d09e41aSPaolo Bonzini void usb_device_handle_data(USBDevice *dev, USBPacket *p);
5450d09e41aSPaolo Bonzini
5460d09e41aSPaolo Bonzini void usb_device_set_interface(USBDevice *dev, int interface,
5470d09e41aSPaolo Bonzini int alt_old, int alt_new);
5480d09e41aSPaolo Bonzini
5490d09e41aSPaolo Bonzini void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep);
5500d09e41aSPaolo Bonzini
5510d09e41aSPaolo Bonzini void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep);
5520d09e41aSPaolo Bonzini
5533b444eadSHans de Goede int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps,
5543b444eadSHans de Goede int streams);
5553b444eadSHans de Goede void usb_device_free_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps);
5563b444eadSHans de Goede
5570d09e41aSPaolo Bonzini const char *usb_device_get_product_desc(USBDevice *dev);
5580d09e41aSPaolo Bonzini
5590d09e41aSPaolo Bonzini const USBDesc *usb_device_get_usb_desc(USBDevice *dev);
5600d09e41aSPaolo Bonzini
usb_device_is_scsi_storage(USBDevice * dev)561b7b2a60bSGerd Hoffmann static inline bool usb_device_is_scsi_storage(USBDevice *dev)
562b7b2a60bSGerd Hoffmann {
563b7b2a60bSGerd Hoffmann return dev->flags & (1 << USB_DEV_FLAG_IS_SCSI_STORAGE);
564b7b2a60bSGerd Hoffmann }
565b7b2a60bSGerd Hoffmann
5660d09e41aSPaolo Bonzini /* quirks.c */
5670d09e41aSPaolo Bonzini
5680d09e41aSPaolo Bonzini /* In bulk endpoints are streaming data sources (iow behave like isoc eps) */
5690d09e41aSPaolo Bonzini #define USB_QUIRK_BUFFER_BULK_IN 0x01
5700d09e41aSPaolo Bonzini /* Bulk pkts in FTDI format, need special handling when combining packets */
5710d09e41aSPaolo Bonzini #define USB_QUIRK_IS_FTDI 0x02
5720d09e41aSPaolo Bonzini
5730d09e41aSPaolo Bonzini int usb_get_quirks(uint16_t vendor_id, uint16_t product_id,
5740d09e41aSPaolo Bonzini uint8_t interface_class, uint8_t interface_subclass,
5750d09e41aSPaolo Bonzini uint8_t interface_protocol);
5760d09e41aSPaolo Bonzini
5770f6dba14SGerd Hoffmann /* pcap.c */
5780f6dba14SGerd Hoffmann void usb_pcap_init(FILE *fp);
5790f6dba14SGerd Hoffmann void usb_pcap_ctrl(USBPacket *p, bool setup);
5800f6dba14SGerd Hoffmann void usb_pcap_data(USBPacket *p, bool setup);
5810f6dba14SGerd Hoffmann
usb_new(const char * name)582*726c6099SPaolo Bonzini static inline USBDevice *usb_new(const char *name)
583*726c6099SPaolo Bonzini {
584*726c6099SPaolo Bonzini return USB_DEVICE(qdev_new(name));
585*726c6099SPaolo Bonzini }
586*726c6099SPaolo Bonzini
usb_try_new(const char * name)587*726c6099SPaolo Bonzini static inline USBDevice *usb_try_new(const char *name)
588*726c6099SPaolo Bonzini {
589*726c6099SPaolo Bonzini return USB_DEVICE(qdev_try_new(name));
590*726c6099SPaolo Bonzini }
591*726c6099SPaolo Bonzini
usb_realize_and_unref(USBDevice * dev,USBBus * bus,Error ** errp)592*726c6099SPaolo Bonzini static inline bool usb_realize_and_unref(USBDevice *dev, USBBus *bus, Error **errp)
593*726c6099SPaolo Bonzini {
594*726c6099SPaolo Bonzini return qdev_realize_and_unref(&dev->qdev, &bus->qbus, errp);
595*726c6099SPaolo Bonzini }
596*726c6099SPaolo Bonzini
usb_create_simple(USBBus * bus,const char * name)597*726c6099SPaolo Bonzini static inline USBDevice *usb_create_simple(USBBus *bus, const char *name)
598*726c6099SPaolo Bonzini {
599*726c6099SPaolo Bonzini USBDevice *dev = usb_new(name);
600*726c6099SPaolo Bonzini
601*726c6099SPaolo Bonzini usb_realize_and_unref(dev, bus, &error_abort);
602*726c6099SPaolo Bonzini return dev;
603*726c6099SPaolo Bonzini }
604*726c6099SPaolo Bonzini
6050d09e41aSPaolo Bonzini #endif
606