xref: /qemu/include/hw/usb.h (revision 5319dc7b)
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 
280d09e41aSPaolo Bonzini #include "hw/qdev.h"
290d09e41aSPaolo Bonzini #include "qemu/queue.h"
300d09e41aSPaolo Bonzini 
310d09e41aSPaolo Bonzini /* Constants related to the USB / PCI interaction */
320d09e41aSPaolo Bonzini #define USB_SBRN    0x60 /* Serial Bus Release Number Register */
330d09e41aSPaolo Bonzini #define USB_RELEASE_1  0x10 /* USB 1.0 */
340d09e41aSPaolo Bonzini #define USB_RELEASE_2  0x20 /* USB 2.0 */
350d09e41aSPaolo Bonzini #define USB_RELEASE_3  0x30 /* USB 3.0 */
360d09e41aSPaolo Bonzini 
370d09e41aSPaolo Bonzini #define USB_TOKEN_SETUP 0x2d
380d09e41aSPaolo Bonzini #define USB_TOKEN_IN    0x69 /* device -> host */
390d09e41aSPaolo Bonzini #define USB_TOKEN_OUT   0xe1 /* host -> device */
400d09e41aSPaolo Bonzini 
410d09e41aSPaolo Bonzini #define USB_RET_SUCCESS           (0)
420d09e41aSPaolo Bonzini #define USB_RET_NODEV             (-1)
430d09e41aSPaolo Bonzini #define USB_RET_NAK               (-2)
440d09e41aSPaolo Bonzini #define USB_RET_STALL             (-3)
450d09e41aSPaolo Bonzini #define USB_RET_BABBLE            (-4)
460d09e41aSPaolo Bonzini #define USB_RET_IOERROR           (-5)
470d09e41aSPaolo Bonzini #define USB_RET_ASYNC             (-6)
480d09e41aSPaolo Bonzini #define USB_RET_ADD_TO_QUEUE      (-7)
490d09e41aSPaolo Bonzini #define USB_RET_REMOVE_FROM_QUEUE (-8)
500d09e41aSPaolo Bonzini 
510d09e41aSPaolo Bonzini #define USB_SPEED_LOW   0
520d09e41aSPaolo Bonzini #define USB_SPEED_FULL  1
530d09e41aSPaolo Bonzini #define USB_SPEED_HIGH  2
540d09e41aSPaolo Bonzini #define USB_SPEED_SUPER 3
550d09e41aSPaolo Bonzini 
560d09e41aSPaolo Bonzini #define USB_SPEED_MASK_LOW   (1 << USB_SPEED_LOW)
570d09e41aSPaolo Bonzini #define USB_SPEED_MASK_FULL  (1 << USB_SPEED_FULL)
580d09e41aSPaolo Bonzini #define USB_SPEED_MASK_HIGH  (1 << USB_SPEED_HIGH)
590d09e41aSPaolo Bonzini #define USB_SPEED_MASK_SUPER (1 << USB_SPEED_SUPER)
600d09e41aSPaolo Bonzini 
610d09e41aSPaolo Bonzini #define USB_STATE_NOTATTACHED 0
620d09e41aSPaolo Bonzini #define USB_STATE_ATTACHED    1
630d09e41aSPaolo Bonzini //#define USB_STATE_POWERED     2
640d09e41aSPaolo Bonzini #define USB_STATE_DEFAULT     3
650d09e41aSPaolo Bonzini //#define USB_STATE_ADDRESS     4
660d09e41aSPaolo Bonzini //#define	USB_STATE_CONFIGURED  5
670d09e41aSPaolo Bonzini #define USB_STATE_SUSPENDED   6
680d09e41aSPaolo Bonzini 
690d09e41aSPaolo Bonzini #define USB_CLASS_AUDIO			1
700d09e41aSPaolo Bonzini #define USB_CLASS_COMM			2
710d09e41aSPaolo Bonzini #define USB_CLASS_HID			3
720d09e41aSPaolo Bonzini #define USB_CLASS_PHYSICAL		5
730d09e41aSPaolo Bonzini #define USB_CLASS_STILL_IMAGE		6
740d09e41aSPaolo Bonzini #define USB_CLASS_PRINTER		7
750d09e41aSPaolo Bonzini #define USB_CLASS_MASS_STORAGE		8
760d09e41aSPaolo Bonzini #define USB_CLASS_HUB			9
770d09e41aSPaolo Bonzini #define USB_CLASS_CDC_DATA		0x0a
780d09e41aSPaolo Bonzini #define USB_CLASS_CSCID			0x0b
790d09e41aSPaolo Bonzini #define USB_CLASS_CONTENT_SEC		0x0d
800d09e41aSPaolo Bonzini #define USB_CLASS_APP_SPEC		0xfe
810d09e41aSPaolo Bonzini #define USB_CLASS_VENDOR_SPEC		0xff
820d09e41aSPaolo Bonzini 
830d09e41aSPaolo Bonzini #define USB_SUBCLASS_UNDEFINED          0
840d09e41aSPaolo Bonzini #define USB_SUBCLASS_AUDIO_CONTROL      1
850d09e41aSPaolo Bonzini #define USB_SUBCLASS_AUDIO_STREAMING    2
860d09e41aSPaolo Bonzini #define USB_SUBCLASS_AUDIO_MIDISTREAMING 3
870d09e41aSPaolo Bonzini 
880d09e41aSPaolo Bonzini #define USB_DIR_OUT			0
890d09e41aSPaolo Bonzini #define USB_DIR_IN			0x80
900d09e41aSPaolo Bonzini 
910d09e41aSPaolo Bonzini #define USB_TYPE_MASK			(0x03 << 5)
920d09e41aSPaolo Bonzini #define USB_TYPE_STANDARD		(0x00 << 5)
930d09e41aSPaolo Bonzini #define USB_TYPE_CLASS			(0x01 << 5)
940d09e41aSPaolo Bonzini #define USB_TYPE_VENDOR			(0x02 << 5)
950d09e41aSPaolo Bonzini #define USB_TYPE_RESERVED		(0x03 << 5)
960d09e41aSPaolo Bonzini 
970d09e41aSPaolo Bonzini #define USB_RECIP_MASK			0x1f
980d09e41aSPaolo Bonzini #define USB_RECIP_DEVICE		0x00
990d09e41aSPaolo Bonzini #define USB_RECIP_INTERFACE		0x01
1000d09e41aSPaolo Bonzini #define USB_RECIP_ENDPOINT		0x02
1010d09e41aSPaolo Bonzini #define USB_RECIP_OTHER			0x03
1020d09e41aSPaolo Bonzini 
1030d09e41aSPaolo Bonzini #define DeviceRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
1040d09e41aSPaolo Bonzini #define DeviceOutRequest ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
1052b81ba53SGerd Hoffmann #define VendorDeviceRequest ((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
1062b81ba53SGerd Hoffmann #define VendorDeviceOutRequest \
1072b81ba53SGerd Hoffmann         ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
1082b81ba53SGerd Hoffmann 
1090d09e41aSPaolo Bonzini #define InterfaceRequest                                        \
1100d09e41aSPaolo Bonzini         ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
1110d09e41aSPaolo Bonzini #define InterfaceOutRequest \
1120d09e41aSPaolo Bonzini         ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
1130d09e41aSPaolo Bonzini #define ClassInterfaceRequest \
1140d09e41aSPaolo Bonzini         ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8)
1150d09e41aSPaolo Bonzini #define ClassInterfaceOutRequest \
1160d09e41aSPaolo Bonzini         ((USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8)
1172b81ba53SGerd Hoffmann #define VendorInterfaceRequest \
1182b81ba53SGerd Hoffmann         ((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE)<<8)
1192b81ba53SGerd Hoffmann #define VendorInterfaceOutRequest \
1202b81ba53SGerd Hoffmann         ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE)<<8)
1212b81ba53SGerd Hoffmann 
1222b81ba53SGerd Hoffmann #define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
1232b81ba53SGerd Hoffmann #define EndpointOutRequest \
1242b81ba53SGerd Hoffmann         ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
1250d09e41aSPaolo Bonzini 
1260d09e41aSPaolo Bonzini #define USB_REQ_GET_STATUS		0x00
1270d09e41aSPaolo Bonzini #define USB_REQ_CLEAR_FEATURE		0x01
1280d09e41aSPaolo Bonzini #define USB_REQ_SET_FEATURE		0x03
1290d09e41aSPaolo Bonzini #define USB_REQ_SET_ADDRESS		0x05
1300d09e41aSPaolo Bonzini #define USB_REQ_GET_DESCRIPTOR		0x06
1310d09e41aSPaolo Bonzini #define USB_REQ_SET_DESCRIPTOR		0x07
1320d09e41aSPaolo Bonzini #define USB_REQ_GET_CONFIGURATION	0x08
1330d09e41aSPaolo Bonzini #define USB_REQ_SET_CONFIGURATION	0x09
1340d09e41aSPaolo Bonzini #define USB_REQ_GET_INTERFACE		0x0A
1350d09e41aSPaolo Bonzini #define USB_REQ_SET_INTERFACE		0x0B
1360d09e41aSPaolo Bonzini #define USB_REQ_SYNCH_FRAME		0x0C
1370d09e41aSPaolo Bonzini 
1380d09e41aSPaolo Bonzini #define USB_DEVICE_SELF_POWERED		0
1390d09e41aSPaolo Bonzini #define USB_DEVICE_REMOTE_WAKEUP	1
1400d09e41aSPaolo Bonzini 
1410d09e41aSPaolo Bonzini #define USB_DT_DEVICE			0x01
1420d09e41aSPaolo Bonzini #define USB_DT_CONFIG			0x02
1430d09e41aSPaolo Bonzini #define USB_DT_STRING			0x03
1440d09e41aSPaolo Bonzini #define USB_DT_INTERFACE		0x04
1450d09e41aSPaolo Bonzini #define USB_DT_ENDPOINT			0x05
1460d09e41aSPaolo Bonzini #define USB_DT_DEVICE_QUALIFIER         0x06
1470d09e41aSPaolo Bonzini #define USB_DT_OTHER_SPEED_CONFIG       0x07
1480d09e41aSPaolo Bonzini #define USB_DT_DEBUG                    0x0A
1490d09e41aSPaolo Bonzini #define USB_DT_INTERFACE_ASSOC          0x0B
1500d09e41aSPaolo Bonzini #define USB_DT_BOS                      0x0F
1510d09e41aSPaolo Bonzini #define USB_DT_DEVICE_CAPABILITY        0x10
1520d09e41aSPaolo Bonzini #define USB_DT_CS_INTERFACE             0x24
1530d09e41aSPaolo Bonzini #define USB_DT_CS_ENDPOINT              0x25
1540d09e41aSPaolo Bonzini #define USB_DT_ENDPOINT_COMPANION       0x30
1550d09e41aSPaolo Bonzini 
1560d09e41aSPaolo Bonzini #define USB_DEV_CAP_WIRELESS            0x01
1570d09e41aSPaolo Bonzini #define USB_DEV_CAP_USB2_EXT            0x02
1580d09e41aSPaolo Bonzini #define USB_DEV_CAP_SUPERSPEED          0x03
1590d09e41aSPaolo Bonzini 
1600d09e41aSPaolo Bonzini #define USB_ENDPOINT_XFER_CONTROL	0
1610d09e41aSPaolo Bonzini #define USB_ENDPOINT_XFER_ISOC		1
1620d09e41aSPaolo Bonzini #define USB_ENDPOINT_XFER_BULK		2
1630d09e41aSPaolo Bonzini #define USB_ENDPOINT_XFER_INT		3
1640d09e41aSPaolo Bonzini #define USB_ENDPOINT_XFER_INVALID     255
1650d09e41aSPaolo Bonzini 
1660d09e41aSPaolo Bonzini #define USB_INTERFACE_INVALID         255
1670d09e41aSPaolo Bonzini 
1680d09e41aSPaolo Bonzini typedef struct USBBus USBBus;
1690d09e41aSPaolo Bonzini typedef struct USBBusOps USBBusOps;
1700d09e41aSPaolo Bonzini typedef struct USBPort USBPort;
1710d09e41aSPaolo Bonzini typedef struct USBDevice USBDevice;
1720d09e41aSPaolo Bonzini typedef struct USBPacket USBPacket;
1730d09e41aSPaolo Bonzini typedef struct USBCombinedPacket USBCombinedPacket;
1740d09e41aSPaolo Bonzini typedef struct USBEndpoint USBEndpoint;
1750d09e41aSPaolo Bonzini 
1760d09e41aSPaolo Bonzini typedef struct USBDesc USBDesc;
1770d09e41aSPaolo Bonzini typedef struct USBDescID USBDescID;
1780d09e41aSPaolo Bonzini typedef struct USBDescDevice USBDescDevice;
1790d09e41aSPaolo Bonzini typedef struct USBDescConfig USBDescConfig;
1800d09e41aSPaolo Bonzini typedef struct USBDescIfaceAssoc USBDescIfaceAssoc;
1810d09e41aSPaolo Bonzini typedef struct USBDescIface USBDescIface;
1820d09e41aSPaolo Bonzini typedef struct USBDescEndpoint USBDescEndpoint;
1830d09e41aSPaolo Bonzini typedef struct USBDescOther USBDescOther;
1840d09e41aSPaolo Bonzini typedef struct USBDescString USBDescString;
185*5319dc7bSGerd Hoffmann typedef struct USBDescMSOS USBDescMSOS;
1860d09e41aSPaolo Bonzini 
1870d09e41aSPaolo Bonzini struct USBDescString {
1880d09e41aSPaolo Bonzini     uint8_t index;
1890d09e41aSPaolo Bonzini     char *str;
1900d09e41aSPaolo Bonzini     QLIST_ENTRY(USBDescString) next;
1910d09e41aSPaolo Bonzini };
1920d09e41aSPaolo Bonzini 
1930d09e41aSPaolo Bonzini #define USB_MAX_ENDPOINTS  15
1940d09e41aSPaolo Bonzini #define USB_MAX_INTERFACES 16
1950d09e41aSPaolo Bonzini 
1960d09e41aSPaolo Bonzini struct USBEndpoint {
1970d09e41aSPaolo Bonzini     uint8_t nr;
1980d09e41aSPaolo Bonzini     uint8_t pid;
1990d09e41aSPaolo Bonzini     uint8_t type;
2000d09e41aSPaolo Bonzini     uint8_t ifnum;
2010d09e41aSPaolo Bonzini     int max_packet_size;
20204b300f8SHans de Goede     int max_streams;
2030d09e41aSPaolo Bonzini     bool pipeline;
2040d09e41aSPaolo Bonzini     bool halted;
2050d09e41aSPaolo Bonzini     USBDevice *dev;
2060d09e41aSPaolo Bonzini     QTAILQ_HEAD(, USBPacket) queue;
2070d09e41aSPaolo Bonzini };
2080d09e41aSPaolo Bonzini 
2090d09e41aSPaolo Bonzini enum USBDeviceFlags {
2100d09e41aSPaolo Bonzini     USB_DEV_FLAG_FULL_PATH,
2110d09e41aSPaolo Bonzini     USB_DEV_FLAG_IS_HOST,
212*5319dc7bSGerd Hoffmann     USB_DEV_FLAG_MSOS_DESC_ENABLE,
213*5319dc7bSGerd Hoffmann     USB_DEV_FLAG_MSOS_DESC_IN_USE,
2140d09e41aSPaolo Bonzini };
2150d09e41aSPaolo Bonzini 
2160d09e41aSPaolo Bonzini /* definition of a USB device */
2170d09e41aSPaolo Bonzini struct USBDevice {
2180d09e41aSPaolo Bonzini     DeviceState qdev;
2190d09e41aSPaolo Bonzini     USBPort *port;
2200d09e41aSPaolo Bonzini     char *port_path;
22171938a09SGerd Hoffmann     char *serial;
2220d09e41aSPaolo Bonzini     void *opaque;
2230d09e41aSPaolo Bonzini     uint32_t flags;
2240d09e41aSPaolo Bonzini 
2250d09e41aSPaolo Bonzini     /* Actual connected speed */
2260d09e41aSPaolo Bonzini     int speed;
2270d09e41aSPaolo Bonzini     /* Supported speeds, not in info because it may be variable (hostdevs) */
2280d09e41aSPaolo Bonzini     int speedmask;
2290d09e41aSPaolo Bonzini     uint8_t addr;
2300d09e41aSPaolo Bonzini     char product_desc[32];
2310d09e41aSPaolo Bonzini     int auto_attach;
2320d09e41aSPaolo Bonzini     int attached;
2330d09e41aSPaolo Bonzini 
2340d09e41aSPaolo Bonzini     int32_t state;
2350d09e41aSPaolo Bonzini     uint8_t setup_buf[8];
2360d09e41aSPaolo Bonzini     uint8_t data_buf[4096];
2370d09e41aSPaolo Bonzini     int32_t remote_wakeup;
2380d09e41aSPaolo Bonzini     int32_t setup_state;
2390d09e41aSPaolo Bonzini     int32_t setup_len;
2400d09e41aSPaolo Bonzini     int32_t setup_index;
2410d09e41aSPaolo Bonzini 
2420d09e41aSPaolo Bonzini     USBEndpoint ep_ctl;
2430d09e41aSPaolo Bonzini     USBEndpoint ep_in[USB_MAX_ENDPOINTS];
2440d09e41aSPaolo Bonzini     USBEndpoint ep_out[USB_MAX_ENDPOINTS];
2450d09e41aSPaolo Bonzini 
2460d09e41aSPaolo Bonzini     QLIST_HEAD(, USBDescString) strings;
2470d09e41aSPaolo Bonzini     const USBDesc *usb_desc; /* Overrides class usb_desc if not NULL */
2480d09e41aSPaolo Bonzini     const USBDescDevice *device;
2490d09e41aSPaolo Bonzini 
2500d09e41aSPaolo Bonzini     int configuration;
2510d09e41aSPaolo Bonzini     int ninterfaces;
2520d09e41aSPaolo Bonzini     int altsetting[USB_MAX_INTERFACES];
2530d09e41aSPaolo Bonzini     const USBDescConfig *config;
2540d09e41aSPaolo Bonzini     const USBDescIface  *ifaces[USB_MAX_INTERFACES];
2550d09e41aSPaolo Bonzini };
2560d09e41aSPaolo Bonzini 
2570d09e41aSPaolo Bonzini #define TYPE_USB_DEVICE "usb-device"
2580d09e41aSPaolo Bonzini #define USB_DEVICE(obj) \
2590d09e41aSPaolo Bonzini      OBJECT_CHECK(USBDevice, (obj), TYPE_USB_DEVICE)
2600d09e41aSPaolo Bonzini #define USB_DEVICE_CLASS(klass) \
2610d09e41aSPaolo Bonzini      OBJECT_CLASS_CHECK(USBDeviceClass, (klass), TYPE_USB_DEVICE)
2620d09e41aSPaolo Bonzini #define USB_DEVICE_GET_CLASS(obj) \
2630d09e41aSPaolo Bonzini      OBJECT_GET_CLASS(USBDeviceClass, (obj), TYPE_USB_DEVICE)
2640d09e41aSPaolo Bonzini 
2650d09e41aSPaolo Bonzini typedef struct USBDeviceClass {
2660d09e41aSPaolo Bonzini     DeviceClass parent_class;
2670d09e41aSPaolo Bonzini 
2680d09e41aSPaolo Bonzini     int (*init)(USBDevice *dev);
2690d09e41aSPaolo Bonzini 
2700d09e41aSPaolo Bonzini     /*
2710d09e41aSPaolo Bonzini      * Walk (enabled) downstream ports, check for a matching device.
2720d09e41aSPaolo Bonzini      * Only hubs implement this.
2730d09e41aSPaolo Bonzini      */
2740d09e41aSPaolo Bonzini     USBDevice *(*find_device)(USBDevice *dev, uint8_t addr);
2750d09e41aSPaolo Bonzini 
2760d09e41aSPaolo Bonzini     /*
2770d09e41aSPaolo Bonzini      * Called when a packet is canceled.
2780d09e41aSPaolo Bonzini      */
2790d09e41aSPaolo Bonzini     void (*cancel_packet)(USBDevice *dev, USBPacket *p);
2800d09e41aSPaolo Bonzini 
2810d09e41aSPaolo Bonzini     /*
2820d09e41aSPaolo Bonzini      * Called when device is destroyed.
2830d09e41aSPaolo Bonzini      */
2840d09e41aSPaolo Bonzini     void (*handle_destroy)(USBDevice *dev);
2850d09e41aSPaolo Bonzini 
2860d09e41aSPaolo Bonzini     /*
2870d09e41aSPaolo Bonzini      * Attach the device
2880d09e41aSPaolo Bonzini      */
2890d09e41aSPaolo Bonzini     void (*handle_attach)(USBDevice *dev);
2900d09e41aSPaolo Bonzini 
2910d09e41aSPaolo Bonzini     /*
2920d09e41aSPaolo Bonzini      * Reset the device
2930d09e41aSPaolo Bonzini      */
2940d09e41aSPaolo Bonzini     void (*handle_reset)(USBDevice *dev);
2950d09e41aSPaolo Bonzini 
2960d09e41aSPaolo Bonzini     /*
2970d09e41aSPaolo Bonzini      * Process control request.
2980d09e41aSPaolo Bonzini      * Called from handle_packet().
2990d09e41aSPaolo Bonzini      *
3000d09e41aSPaolo Bonzini      * Status gets stored in p->status, and if p->status == USB_RET_SUCCESS
3010d09e41aSPaolo Bonzini      * then the number of bytes transferred is stored in p->actual_length
3020d09e41aSPaolo Bonzini      */
3030d09e41aSPaolo Bonzini     void (*handle_control)(USBDevice *dev, USBPacket *p, int request, int value,
3040d09e41aSPaolo Bonzini                            int index, int length, uint8_t *data);
3050d09e41aSPaolo Bonzini 
3060d09e41aSPaolo Bonzini     /*
3070d09e41aSPaolo Bonzini      * Process data transfers (both BULK and ISOC).
3080d09e41aSPaolo Bonzini      * Called from handle_packet().
3090d09e41aSPaolo Bonzini      *
3100d09e41aSPaolo Bonzini      * Status gets stored in p->status, and if p->status == USB_RET_SUCCESS
3110d09e41aSPaolo Bonzini      * then the number of bytes transferred is stored in p->actual_length
3120d09e41aSPaolo Bonzini      */
3130d09e41aSPaolo Bonzini     void (*handle_data)(USBDevice *dev, USBPacket *p);
3140d09e41aSPaolo Bonzini 
3150d09e41aSPaolo Bonzini     void (*set_interface)(USBDevice *dev, int interface,
3160d09e41aSPaolo Bonzini                           int alt_old, int alt_new);
3170d09e41aSPaolo Bonzini 
3180d09e41aSPaolo Bonzini     /*
3190d09e41aSPaolo Bonzini      * Called when the hcd is done queuing packets for an endpoint, only
3200d09e41aSPaolo Bonzini      * necessary for devices which can return USB_RET_ADD_TO_QUEUE.
3210d09e41aSPaolo Bonzini      */
3220d09e41aSPaolo Bonzini     void (*flush_ep_queue)(USBDevice *dev, USBEndpoint *ep);
3230d09e41aSPaolo Bonzini 
3240d09e41aSPaolo Bonzini     /*
3250d09e41aSPaolo Bonzini      * Called by the hcd to let the device know the queue for an endpoint
3260d09e41aSPaolo Bonzini      * has been unlinked / stopped. Optional may be NULL.
3270d09e41aSPaolo Bonzini      */
3280d09e41aSPaolo Bonzini     void (*ep_stopped)(USBDevice *dev, USBEndpoint *ep);
3290d09e41aSPaolo Bonzini 
3303b444eadSHans de Goede     /*
3313b444eadSHans de Goede      * Called by the hcd to alloc / free streams on a bulk endpoint.
3323b444eadSHans de Goede      * Optional may be NULL.
3333b444eadSHans de Goede      */
3343b444eadSHans de Goede     int (*alloc_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps,
3353b444eadSHans de Goede                          int streams);
3363b444eadSHans de Goede     void (*free_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps);
3373b444eadSHans de Goede 
3380d09e41aSPaolo Bonzini     const char *product_desc;
3390d09e41aSPaolo Bonzini     const USBDesc *usb_desc;
3400d09e41aSPaolo Bonzini } USBDeviceClass;
3410d09e41aSPaolo Bonzini 
3420d09e41aSPaolo Bonzini typedef struct USBPortOps {
3430d09e41aSPaolo Bonzini     void (*attach)(USBPort *port);
3440d09e41aSPaolo Bonzini     void (*detach)(USBPort *port);
3450d09e41aSPaolo Bonzini     /*
3460d09e41aSPaolo Bonzini      * This gets called when a device downstream from the device attached to
3470d09e41aSPaolo Bonzini      * the port (iow attached through a hub) gets detached.
3480d09e41aSPaolo Bonzini      */
3490d09e41aSPaolo Bonzini     void (*child_detach)(USBPort *port, USBDevice *child);
3500d09e41aSPaolo Bonzini     void (*wakeup)(USBPort *port);
3510d09e41aSPaolo Bonzini     /*
3520d09e41aSPaolo Bonzini      * Note that port->dev will be different then the device from which
3530d09e41aSPaolo Bonzini      * the packet originated when a hub is involved.
3540d09e41aSPaolo Bonzini      */
3550d09e41aSPaolo Bonzini     void (*complete)(USBPort *port, USBPacket *p);
3560d09e41aSPaolo Bonzini } USBPortOps;
3570d09e41aSPaolo Bonzini 
3580d09e41aSPaolo Bonzini /* USB port on which a device can be connected */
3590d09e41aSPaolo Bonzini struct USBPort {
3600d09e41aSPaolo Bonzini     USBDevice *dev;
3610d09e41aSPaolo Bonzini     int speedmask;
36247b5264eSAnthony Liguori     int hubcount;
3630d09e41aSPaolo Bonzini     char path[16];
3640d09e41aSPaolo Bonzini     USBPortOps *ops;
3650d09e41aSPaolo Bonzini     void *opaque;
3660d09e41aSPaolo Bonzini     int index; /* internal port index, may be used with the opaque */
3670d09e41aSPaolo Bonzini     QTAILQ_ENTRY(USBPort) next;
3680d09e41aSPaolo Bonzini };
3690d09e41aSPaolo Bonzini 
3700d09e41aSPaolo Bonzini typedef void USBCallback(USBPacket * packet, void *opaque);
3710d09e41aSPaolo Bonzini 
3720d09e41aSPaolo Bonzini typedef enum USBPacketState {
3730d09e41aSPaolo Bonzini     USB_PACKET_UNDEFINED = 0,
3740d09e41aSPaolo Bonzini     USB_PACKET_SETUP,
3750d09e41aSPaolo Bonzini     USB_PACKET_QUEUED,
3760d09e41aSPaolo Bonzini     USB_PACKET_ASYNC,
3770d09e41aSPaolo Bonzini     USB_PACKET_COMPLETE,
3780d09e41aSPaolo Bonzini     USB_PACKET_CANCELED,
3790d09e41aSPaolo Bonzini } USBPacketState;
3800d09e41aSPaolo Bonzini 
3810d09e41aSPaolo Bonzini /* Structure used to hold information about an active USB packet.  */
3820d09e41aSPaolo Bonzini struct USBPacket {
3830d09e41aSPaolo Bonzini     /* Data fields for use by the driver.  */
3840d09e41aSPaolo Bonzini     int pid;
3850d09e41aSPaolo Bonzini     uint64_t id;
3860d09e41aSPaolo Bonzini     USBEndpoint *ep;
3870d09e41aSPaolo Bonzini     unsigned int stream;
3880d09e41aSPaolo Bonzini     QEMUIOVector iov;
3890d09e41aSPaolo Bonzini     uint64_t parameter; /* control transfers */
3900d09e41aSPaolo Bonzini     bool short_not_ok;
3910d09e41aSPaolo Bonzini     bool int_req;
3920d09e41aSPaolo Bonzini     int status; /* USB_RET_* status code */
3930d09e41aSPaolo Bonzini     int actual_length; /* Number of bytes actually transferred */
3940d09e41aSPaolo Bonzini     /* Internal use by the USB layer.  */
3950d09e41aSPaolo Bonzini     USBPacketState state;
3960d09e41aSPaolo Bonzini     USBCombinedPacket *combined;
3970d09e41aSPaolo Bonzini     QTAILQ_ENTRY(USBPacket) queue;
3980d09e41aSPaolo Bonzini     QTAILQ_ENTRY(USBPacket) combined_entry;
3990d09e41aSPaolo Bonzini };
4000d09e41aSPaolo Bonzini 
4010d09e41aSPaolo Bonzini struct USBCombinedPacket {
4020d09e41aSPaolo Bonzini     USBPacket *first;
4030d09e41aSPaolo Bonzini     QTAILQ_HEAD(packets_head, USBPacket) packets;
4040d09e41aSPaolo Bonzini     QEMUIOVector iov;
4050d09e41aSPaolo Bonzini };
4060d09e41aSPaolo Bonzini 
4070d09e41aSPaolo Bonzini void usb_packet_init(USBPacket *p);
4080d09e41aSPaolo Bonzini void usb_packet_set_state(USBPacket *p, USBPacketState state);
4090d09e41aSPaolo Bonzini void usb_packet_check_state(USBPacket *p, USBPacketState expected);
4100d09e41aSPaolo Bonzini void usb_packet_setup(USBPacket *p, int pid,
4110d09e41aSPaolo Bonzini                       USBEndpoint *ep, unsigned int stream,
4120d09e41aSPaolo Bonzini                       uint64_t id, bool short_not_ok, bool int_req);
4130d09e41aSPaolo Bonzini void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len);
4140d09e41aSPaolo Bonzini int usb_packet_map(USBPacket *p, QEMUSGList *sgl);
4150d09e41aSPaolo Bonzini void usb_packet_unmap(USBPacket *p, QEMUSGList *sgl);
4160d09e41aSPaolo Bonzini void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes);
4170d09e41aSPaolo Bonzini void usb_packet_skip(USBPacket *p, size_t bytes);
4180d09e41aSPaolo Bonzini size_t usb_packet_size(USBPacket *p);
4190d09e41aSPaolo Bonzini void usb_packet_cleanup(USBPacket *p);
4200d09e41aSPaolo Bonzini 
4210d09e41aSPaolo Bonzini static inline bool usb_packet_is_inflight(USBPacket *p)
4220d09e41aSPaolo Bonzini {
4230d09e41aSPaolo Bonzini     return (p->state == USB_PACKET_QUEUED ||
4240d09e41aSPaolo Bonzini             p->state == USB_PACKET_ASYNC);
4250d09e41aSPaolo Bonzini }
4260d09e41aSPaolo Bonzini 
4270d09e41aSPaolo Bonzini USBDevice *usb_find_device(USBPort *port, uint8_t addr);
4280d09e41aSPaolo Bonzini 
4290d09e41aSPaolo Bonzini void usb_handle_packet(USBDevice *dev, USBPacket *p);
4300d09e41aSPaolo Bonzini void usb_packet_complete(USBDevice *dev, USBPacket *p);
4310d09e41aSPaolo Bonzini void usb_packet_complete_one(USBDevice *dev, USBPacket *p);
4320d09e41aSPaolo Bonzini void usb_cancel_packet(USBPacket * p);
4330d09e41aSPaolo Bonzini 
4340d09e41aSPaolo Bonzini void usb_ep_init(USBDevice *dev);
4350d09e41aSPaolo Bonzini void usb_ep_reset(USBDevice *dev);
4360d09e41aSPaolo Bonzini void usb_ep_dump(USBDevice *dev);
4370d09e41aSPaolo Bonzini struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep);
4380d09e41aSPaolo Bonzini uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep);
4390d09e41aSPaolo Bonzini uint8_t usb_ep_get_ifnum(USBDevice *dev, int pid, int ep);
4400d09e41aSPaolo Bonzini void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type);
4410d09e41aSPaolo Bonzini void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum);
4420d09e41aSPaolo Bonzini void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
4430d09e41aSPaolo Bonzini                                 uint16_t raw);
4440d09e41aSPaolo Bonzini int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep);
44504b300f8SHans de Goede void usb_ep_set_max_streams(USBDevice *dev, int pid, int ep, uint8_t raw);
44604b300f8SHans de Goede int usb_ep_get_max_streams(USBDevice *dev, int pid, int ep);
4470d09e41aSPaolo Bonzini void usb_ep_set_pipeline(USBDevice *dev, int pid, int ep, bool enabled);
4480d09e41aSPaolo Bonzini void usb_ep_set_halted(USBDevice *dev, int pid, int ep, bool halted);
4490d09e41aSPaolo Bonzini USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep,
4500d09e41aSPaolo Bonzini                                     uint64_t id);
4510d09e41aSPaolo Bonzini 
4520d09e41aSPaolo Bonzini void usb_ep_combine_input_packets(USBEndpoint *ep);
4530d09e41aSPaolo Bonzini void usb_combined_input_packet_complete(USBDevice *dev, USBPacket *p);
4540d09e41aSPaolo Bonzini void usb_combined_packet_cancel(USBDevice *dev, USBPacket *p);
4550d09e41aSPaolo Bonzini 
4560d09e41aSPaolo Bonzini void usb_attach(USBPort *port);
4570d09e41aSPaolo Bonzini void usb_detach(USBPort *port);
4580d09e41aSPaolo Bonzini void usb_port_reset(USBPort *port);
4590d09e41aSPaolo Bonzini void usb_device_reset(USBDevice *dev);
4600d09e41aSPaolo Bonzini void usb_wakeup(USBEndpoint *ep, unsigned int stream);
4610d09e41aSPaolo Bonzini void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p);
4620d09e41aSPaolo Bonzini int set_usb_string(uint8_t *buf, const char *str);
4630d09e41aSPaolo Bonzini 
4640d09e41aSPaolo Bonzini /* usb-linux.c */
4650d09e41aSPaolo Bonzini USBDevice *usb_host_device_open(USBBus *bus, const char *devname);
4660d09e41aSPaolo Bonzini void usb_host_info(Monitor *mon, const QDict *qdict);
4670d09e41aSPaolo Bonzini 
4680d09e41aSPaolo Bonzini /* usb ports of the VM */
4690d09e41aSPaolo Bonzini 
4700d09e41aSPaolo Bonzini #define VM_USB_HUB_SIZE 8
4710d09e41aSPaolo Bonzini 
4720d09e41aSPaolo Bonzini /* usb-musb.c */
4730d09e41aSPaolo Bonzini enum musb_irq_source_e {
4740d09e41aSPaolo Bonzini     musb_irq_suspend = 0,
4750d09e41aSPaolo Bonzini     musb_irq_resume,
4760d09e41aSPaolo Bonzini     musb_irq_rst_babble,
4770d09e41aSPaolo Bonzini     musb_irq_sof,
4780d09e41aSPaolo Bonzini     musb_irq_connect,
4790d09e41aSPaolo Bonzini     musb_irq_disconnect,
4800d09e41aSPaolo Bonzini     musb_irq_vbus_request,
4810d09e41aSPaolo Bonzini     musb_irq_vbus_error,
4820d09e41aSPaolo Bonzini     musb_irq_rx,
4830d09e41aSPaolo Bonzini     musb_irq_tx,
4840d09e41aSPaolo Bonzini     musb_set_vbus,
4850d09e41aSPaolo Bonzini     musb_set_session,
4860d09e41aSPaolo Bonzini     /* Add new interrupts here */
4870d09e41aSPaolo Bonzini     musb_irq_max, /* total number of interrupts defined */
4880d09e41aSPaolo Bonzini };
4890d09e41aSPaolo Bonzini 
4900d09e41aSPaolo Bonzini typedef struct MUSBState MUSBState;
4910d09e41aSPaolo Bonzini MUSBState *musb_init(DeviceState *parent_device, int gpio_base);
4920d09e41aSPaolo Bonzini void musb_reset(MUSBState *s);
4930d09e41aSPaolo Bonzini uint32_t musb_core_intr_get(MUSBState *s);
4940d09e41aSPaolo Bonzini void musb_core_intr_clear(MUSBState *s, uint32_t mask);
4950d09e41aSPaolo Bonzini void musb_set_size(MUSBState *s, int epnum, int size, int is_tx);
4960d09e41aSPaolo Bonzini 
4970d09e41aSPaolo Bonzini /* usb-bus.c */
4980d09e41aSPaolo Bonzini 
4990d09e41aSPaolo Bonzini #define TYPE_USB_BUS "usb-bus"
5000d09e41aSPaolo Bonzini #define USB_BUS(obj) OBJECT_CHECK(USBBus, (obj), TYPE_USB_BUS)
5010d09e41aSPaolo Bonzini 
5020d09e41aSPaolo Bonzini struct USBBus {
5030d09e41aSPaolo Bonzini     BusState qbus;
5040d09e41aSPaolo Bonzini     USBBusOps *ops;
5050d09e41aSPaolo Bonzini     int busnr;
5060d09e41aSPaolo Bonzini     int nfree;
5070d09e41aSPaolo Bonzini     int nused;
5080d09e41aSPaolo Bonzini     QTAILQ_HEAD(, USBPort) free;
5090d09e41aSPaolo Bonzini     QTAILQ_HEAD(, USBPort) used;
5100d09e41aSPaolo Bonzini     QTAILQ_ENTRY(USBBus) next;
5110d09e41aSPaolo Bonzini };
5120d09e41aSPaolo Bonzini 
5130d09e41aSPaolo Bonzini struct USBBusOps {
5140d09e41aSPaolo Bonzini     int (*register_companion)(USBBus *bus, USBPort *ports[],
5150d09e41aSPaolo Bonzini                               uint32_t portcount, uint32_t firstport);
5160d09e41aSPaolo Bonzini     void (*wakeup_endpoint)(USBBus *bus, USBEndpoint *ep, unsigned int stream);
5170d09e41aSPaolo Bonzini };
5180d09e41aSPaolo Bonzini 
519c889b3a5SAndreas Färber void usb_bus_new(USBBus *bus, size_t bus_size,
520c889b3a5SAndreas Färber                  USBBusOps *ops, DeviceState *host);
5210d09e41aSPaolo Bonzini USBBus *usb_bus_find(int busnr);
5220d09e41aSPaolo Bonzini void usb_legacy_register(const char *typename, const char *usbdevice_name,
5230d09e41aSPaolo Bonzini                          USBDevice *(*usbdevice_init)(USBBus *bus,
5240d09e41aSPaolo Bonzini                                                       const char *params));
5250d09e41aSPaolo Bonzini USBDevice *usb_create(USBBus *bus, const char *name);
5260d09e41aSPaolo Bonzini USBDevice *usb_create_simple(USBBus *bus, const char *name);
5270d09e41aSPaolo Bonzini USBDevice *usbdevice_create(const char *cmdline);
5280d09e41aSPaolo Bonzini void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
5290d09e41aSPaolo Bonzini                        USBPortOps *ops, int speedmask);
5300d09e41aSPaolo Bonzini int usb_register_companion(const char *masterbus, USBPort *ports[],
5310d09e41aSPaolo Bonzini                            uint32_t portcount, uint32_t firstport,
5320d09e41aSPaolo Bonzini                            void *opaque, USBPortOps *ops, int speedmask);
5330d09e41aSPaolo Bonzini void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr);
5340d09e41aSPaolo Bonzini void usb_unregister_port(USBBus *bus, USBPort *port);
5350d09e41aSPaolo Bonzini int usb_claim_port(USBDevice *dev);
5360d09e41aSPaolo Bonzini void usb_release_port(USBDevice *dev);
5370d09e41aSPaolo Bonzini int usb_device_attach(USBDevice *dev);
5380d09e41aSPaolo Bonzini int usb_device_detach(USBDevice *dev);
5390d09e41aSPaolo Bonzini int usb_device_delete_addr(int busnr, int addr);
5400d09e41aSPaolo Bonzini 
5410d09e41aSPaolo Bonzini static inline USBBus *usb_bus_from_device(USBDevice *d)
5420d09e41aSPaolo Bonzini {
5430d09e41aSPaolo Bonzini     return DO_UPCAST(USBBus, qbus, d->qdev.parent_bus);
5440d09e41aSPaolo Bonzini }
5450d09e41aSPaolo Bonzini 
5460d09e41aSPaolo Bonzini extern const VMStateDescription vmstate_usb_device;
5470d09e41aSPaolo Bonzini 
5480d09e41aSPaolo Bonzini #define VMSTATE_USB_DEVICE(_field, _state) {                         \
5490d09e41aSPaolo Bonzini     .name       = (stringify(_field)),                               \
5500d09e41aSPaolo Bonzini     .size       = sizeof(USBDevice),                                 \
5510d09e41aSPaolo Bonzini     .vmsd       = &vmstate_usb_device,                               \
5520d09e41aSPaolo Bonzini     .flags      = VMS_STRUCT,                                        \
5530d09e41aSPaolo Bonzini     .offset     = vmstate_offset_value(_state, _field, USBDevice),   \
5540d09e41aSPaolo Bonzini }
5550d09e41aSPaolo Bonzini 
5560d09e41aSPaolo Bonzini USBDevice *usb_device_find_device(USBDevice *dev, uint8_t addr);
5570d09e41aSPaolo Bonzini 
5580d09e41aSPaolo Bonzini void usb_device_cancel_packet(USBDevice *dev, USBPacket *p);
5590d09e41aSPaolo Bonzini 
5600d09e41aSPaolo Bonzini void usb_device_handle_attach(USBDevice *dev);
5610d09e41aSPaolo Bonzini 
5620d09e41aSPaolo Bonzini void usb_device_handle_reset(USBDevice *dev);
5630d09e41aSPaolo Bonzini 
5640d09e41aSPaolo Bonzini void usb_device_handle_control(USBDevice *dev, USBPacket *p, int request,
5650d09e41aSPaolo Bonzini                                int val, int index, int length, uint8_t *data);
5660d09e41aSPaolo Bonzini 
5670d09e41aSPaolo Bonzini void usb_device_handle_data(USBDevice *dev, USBPacket *p);
5680d09e41aSPaolo Bonzini 
5690d09e41aSPaolo Bonzini void usb_device_set_interface(USBDevice *dev, int interface,
5700d09e41aSPaolo Bonzini                               int alt_old, int alt_new);
5710d09e41aSPaolo Bonzini 
5720d09e41aSPaolo Bonzini void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep);
5730d09e41aSPaolo Bonzini 
5740d09e41aSPaolo Bonzini void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep);
5750d09e41aSPaolo Bonzini 
5763b444eadSHans de Goede int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps,
5773b444eadSHans de Goede                              int streams);
5783b444eadSHans de Goede void usb_device_free_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps);
5793b444eadSHans de Goede 
5800d09e41aSPaolo Bonzini const char *usb_device_get_product_desc(USBDevice *dev);
5810d09e41aSPaolo Bonzini 
5820d09e41aSPaolo Bonzini const USBDesc *usb_device_get_usb_desc(USBDevice *dev);
5830d09e41aSPaolo Bonzini 
5840d09e41aSPaolo Bonzini int ehci_create_ich9_with_companions(PCIBus *bus, int slot);
5850d09e41aSPaolo Bonzini 
5860d09e41aSPaolo Bonzini /* quirks.c */
5870d09e41aSPaolo Bonzini 
5880d09e41aSPaolo Bonzini /* In bulk endpoints are streaming data sources (iow behave like isoc eps) */
5890d09e41aSPaolo Bonzini #define USB_QUIRK_BUFFER_BULK_IN	0x01
5900d09e41aSPaolo Bonzini /* Bulk pkts in FTDI format, need special handling when combining packets */
5910d09e41aSPaolo Bonzini #define USB_QUIRK_IS_FTDI		0x02
5920d09e41aSPaolo Bonzini 
5930d09e41aSPaolo Bonzini int usb_get_quirks(uint16_t vendor_id, uint16_t product_id,
5940d09e41aSPaolo Bonzini                    uint8_t interface_class, uint8_t interface_subclass,
5950d09e41aSPaolo Bonzini                    uint8_t interface_protocol);
5960d09e41aSPaolo Bonzini 
5970d09e41aSPaolo Bonzini #endif
598