1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
#ifndef QEMU_HW_USB_DESC_H
#define QEMU_HW_USB_DESC_H
#include <inttypes.h>
struct USBDescID {
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
};
struct USBDescDevice {
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint8_t bNumConfigurations;
const USBDescConfig *confs;
};
struct USBDescConfig {
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
/* grouped interfaces */
uint8_t nif_groups;
const USBDescIfaceAssoc *if_groups;
/* "normal" interfaces */
uint8_t nif;
const USBDescIface *ifs;
};
/* conceptually an Interface Association Descriptor, and releated interfaces */
struct USBDescIfaceAssoc {
uint8_t bFirstInterface;
uint8_t bInterfaceCount;
uint8_t bFunctionClass;
uint8_t bFunctionSubClass;
uint8_t bFunctionProtocol;
uint8_t iFunction;
uint8_t nif;
const USBDescIface *ifs;
};
struct USBDescIface {
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
uint8_t ndesc;
USBDescOther *descs;
USBDescEndpoint *eps;
};
struct USBDescEndpoint {
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
uint8_t bRefresh;
uint8_t bSynchAddress;
uint8_t is_audio; /* has bRefresh + bSynchAddress */
uint8_t *extra;
};
struct USBDescOther {
uint8_t length;
const uint8_t *data;
};
typedef const char *USBDescStrings[256];
struct USBDesc {
USBDescID id;
const USBDescDevice *full;
const USBDescDevice *high;
const char* const *str;
};
/* generate usb packages from structs */
int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
uint8_t *dest, size_t len);
int usb_desc_device_qualifier(const USBDescDevice *dev,
uint8_t *dest, size_t len);
int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len);
int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest,
size_t len);
int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len);
int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len);
int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
/* control message emulation helpers */
void usb_desc_init(USBDevice *dev);
void usb_desc_attach(USBDevice *dev);
void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str);
const char *usb_desc_get_string(USBDevice *dev, uint8_t index);
int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len);
int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len);
int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
int request, int value, int index, int length, uint8_t *data);
#endif /* QEMU_HW_USB_DESC_H */
|