summaryrefslogtreecommitdiff
path: root/tools/src/usb_types.h
blob: 2571a1a42c4d66bac9ead46c845da577b3d44e32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/* SPDX-License-Identifier: MIT */

#ifndef USB_TYPES_H
#define USB_TYPES_H

#include "types.h"

#define USB_REQUEST_TYPE_DIRECTION_SHIFT       7
#define USB_REQUEST_TYPE_DIRECTION(d)          ((d) << USB_REQUEST_TYPE_DIRECTION_SHIFT)
#define USB_REQUEST_TYPE_DIRECTION_HOST2DEVICE 0
#define USB_REQUEST_TYPE_DIRECTION_DEVICE2HOST 1

#define USB_REQUEST_TYPE_SHIFT    5
#define USB_REQUEST_TYPE(t)       ((t) << USB_REQUEST_TYPE_SHIFT)
#define USB_REQUEST_TYPE_STANDARD USB_REQUEST_TYPE(0b00)
#define USB_REQUEST_TYPE_CLASS    USB_REQUEST_TYPE(0b01)
#define USB_REQUEST_TYPE_VENDOR   USB_REQUEST_TYPE(0b10)
#define USB_REQUEST_TYPE_MASK     USB_REQUEST_TYPE(0b11)

#define USB_REQUEST_TYPE_RECIPIENT_DEVICE    0
#define USB_REQUEST_TYPE_RECIPIENT_INTERFACE 1
#define USB_REQUEST_TYPE_RECIPIENT_ENDPOINT  2
#define USB_REQUEST_TYPE_RECIPIENT_OTHER     3
#define USB_REQUEST_TYPE_RECIPIENT_MASK      0b11

#define USB_REQUEST_GET_STATUS        0x00
#define USB_REQUEST_CLEAR_FEATURE     0x01
#define USB_REQUEST_SET_FEATURE       0x03
#define USB_REQUEST_SET_ADDRESS       0x05
#define USB_REQUEST_GET_DESCRIPTOR    0x06
#define USB_REQUEST_SET_DESCRIPTOR    0x07
#define USB_REQUEST_GET_CONFIGURATION 0x08
#define USB_REQUEST_SET_CONFIGURATION 0x09

#define USB_EP_REQUEST_CLEAR_FEATURE 0x01
#define USB_EP_REQUEST_SET_FEATURE   0x03

#define USB_FEATURE_ENDPOINT_HALT 0x00

#define USB_REQUEST_CDC_SET_LINE_CODING     0x20
#define USB_REQUEST_CDC_GET_LINE_CODING     0x21
#define USB_REQUEST_CDC_SET_CTRL_LINE_STATE 0x22

struct usb_setup_packet_raw {
    u8 bmRequestType;
    u8 bRequest;
    u16 wValue;
    u16 wIndex;
    u16 wLength;
} PACKED;

struct usb_setup_packet_get_descriptor {
    u8 bmRequestType;
    u8 bRequest;
    u8 index;
    u8 type;
    u16 language;
    u16 wLength;
} PACKED;

struct usb_set_packet_set_address {
    u8 bmRequestType;
    u8 bRequest;
    u16 address;
    u16 zero0;
    u16 zero1;
} PACKED;

struct usb_set_packet_set_configuration {
    u8 bmRequestType;
    u8 bRequest;
    u16 configuration;
    u16 zero0;
    u16 zero1;
} PACKED;

struct usb_setup_packet_feature {
    u8 bmRequestType;
    u8 bRequest;
    u16 wFeatureSelector;
    u16 wEndpoint;
    u16 wLength;
} PACKED;

union usb_setup_packet {
    struct usb_setup_packet_raw raw;
    struct usb_setup_packet_get_descriptor get_descriptor;
    struct usb_set_packet_set_address set_address;
    struct usb_set_packet_set_configuration set_configuration;
    struct usb_setup_packet_feature feature;
};

#define USB_DEVICE_DESCRIPTOR                    0x01
#define USB_CONFIGURATION_DESCRIPTOR             0x02
#define USB_STRING_DESCRIPTOR                    0x03
#define USB_INTERFACE_DESCRIPTOR                 0x04
#define USB_ENDPOINT_DESCRIPTOR                  0x05
#define USB_DEVICE_QUALIFIER_DESCRIPTOR          0x06
#define USB_OTHER_SPEED_CONFIGURATION_DESCRIPTOR 0x07

#define USB_CDC_INTERFACE_FUNCTIONAL_DESCRIPTOR 0x24
#define USB_CDC_UNION_SUBTYPE                   0x06

#define USB_CONFIGURATION_SELF_POWERED   0x40
#define USB_CONFIGURATION_ATTRIBUTE_RES1 0x80

#define USB_ENDPOINT_ADDR_IN(ep)  (0x80 | (ep))
#define USB_ENDPOINT_ADDR_OUT(ep) (0x00 | (ep))

#define USB_ENDPOINT_ATTR_TYPE_CONTROL     0b00
#define USB_ENDPOINT_ATTR_TYPE_ISOCHRONOUS 0b01
#define USB_ENDPOINT_ATTR_TYPE_BULK        0b10
#define USB_ENDPOINT_ATTR_TYPE_INTERRUPT   0b11

#define USB_LANGID_EN_US 0x0409

struct usb_device_descriptor {
    u8 bLength;
    u8 bDescriptorType;
    u16 bcdUSB;
    u8 bDeviceClass;
    u8 bDeviceSubClass;
    u8 bDeviceProtocol;
    u8 bMaxPacketSize0;
    u16 idVendor;
    u16 idProduct;
    u16 bcdDevice;
    u8 iManufacturer;
    u8 iProduct;
    u8 iSerialNumber;
    u8 bNumConfigurations;
} PACKED;

struct usb_configuration_descriptor {
    u8 bLength;
    u8 bDescriptorType;
    u16 wTotalLength;
    u8 bNumInterfaces;
    u8 bConfigurationValue;
    u8 iConfiguration;
    u8 bmAttributes;
    u8 bMaxPower;
} PACKED;

struct usb_interface_descriptor {
    u8 bLength;
    u8 bDescriptorType;
    u8 bInterfaceNumber;
    u8 bAlternateSetting;
    u8 bNumEndpoints;
    u8 bInterfaceClass;
    u8 bInterfaceSubClass;
    u8 bInterfaceProtocol;
    u8 iInterface;
} PACKED;

struct usb_endpoint_descriptor {
    u8 bLength;
    u8 bDescriptorType;
    u8 bEndpointAddress;
    u8 bmAttributes;
    u16 wMaxPacketSize;
    u8 bInterval;
} PACKED;

struct usb_string_descriptor {
    u8 bLength;
    u8 bDescriptorType;
    u16 bString[];
} PACKED;

struct usb_string_descriptor_languages {
    u8 bLength;
    u8 bDescriptorType;
    u16 wLANGID[];
} PACKED;

struct cdc_union_functional_descriptor {
    u8 bFunctionLength;
    u8 bDescriptorType;
    u8 bDescriptorSubtype;
    u8 bControlInterface;
    u8 bDataInterface;
} PACKED;

struct usb_device_qualifier_descriptor {
    u8 bLength;
    u8 bDescriptorType;
    u16 bcdUSB;
    u8 bDeviceClass;
    u8 bDeviceSubClass;
    u8 bDeviceProtocol;
    u8 bMaxPacketSize0;
    u8 bNumConfigurations;
    u8 bReserved;
} PACKED;

/*
 * this macro is required because we need to convert any string literals
 * to UTF16 and because we need to calculate the correct total size of the
 * string descriptor.
 */
#define make_usb_string_descriptor(str)                                                            \
    {                                                                                              \
        .bLength = sizeof(struct usb_string_descriptor) + sizeof(u##str),                          \
        .bDescriptorType = USB_STRING_DESCRIPTOR, .bString = u##str                                \
    }

#endif