xref: /qemu/include/hw/usb.h (revision ccced963)
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