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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
|
/*****************************************************************************
* Copyright (c) 2013 IBM Corporation
* All rights reserved.
* This program and the accompanying materials
* are made available under the terms of the BSD License
* which accompanies this distribution, and is available at
* http://www.opensource.org/licenses/bsd-license.php
*
* Contributors:
* IBM Corporation - initial implementation
*****************************************************************************/
#ifndef __USB_CORE_H
#define __USB_CORE_H
#include <stdio.h>
#include <stdbool.h>
#include "helpers.h"
#include "usb.h"
#include "tools.h"
enum usb_hcd_type {
USB_OHCI = 1,
USB_EHCI = 2,
USB_XHCI = 3,
};
struct usb_hcd_dev;
struct usb_hcd_dev {
void *base;
long type;
long num;
struct usb_hcd_ops *ops;
void *priv; /* hcd owned structure */
long nextaddr; /* address for devices */
};
struct usb_pipe;
/*******************************************/
/* Standard Endpoint Descriptor */
/*******************************************/
/* bmAttributes */
#define USB_EP_TYPE_MASK 0x03
#define USB_EP_TYPE_CONTROL 0
#define USB_EP_TYPE_ISOC 1
#define USB_EP_TYPE_BULK 2
#define USB_EP_TYPE_INTR 3
struct usb_ep_descr {
uint8_t bLength; /* size of descriptor */
uint8_t bDescriptorType; /* Type = 5 */
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} __attribute__((packed));
#define DEV_HID_KEYB 0x030101 /* class=HIB, protocol=Keyboard */
#define DEV_HID_MOUSE 0x030102 /* class=HIB, protocol=Mouse */
#define DEV_HUB 0x090000 /* class=HUB, subclass, protocol */
#define DEV_MASS_RBC 0x080150 /* MassStorage, RBC, Bulk */
#define DEV_CDROM_ATAPI 0x080250 /* MassStorage, SFF-8020i , Bulk */
#define DEV_MASS_FLOPPY 0x080450 /* MassStorage, UFI, Bulk */
#define DEV_MASS_ATAPI 0x080550 /* MassStorage, SFF-8070i , Bulk */
#define DEV_MASS_SCSI 0x080650 /* MassStorage, SCSI, Bulk */
enum USB_SPEED_TYPE {
USB_LOW_SPEED = 0,
USB_FULL_SPEED = 1,
USB_HIGH_SPEED = 2,
USB_SUPER_SPEED = 3,
};
/* Max number of endpoints supported in a device */
#define USB_DEV_EP_MAX 4
#define USB_TIMEOUT 5000 /* 5 sec usb timeout */
struct usb_dev {
struct usb_dev *next;
struct usb_hcd_dev *hcidev;
struct usb_pipe *intr;
struct usb_pipe *control;
struct usb_pipe *bulk_in;
struct usb_pipe *bulk_out;
struct usb_ep_descr ep[USB_DEV_EP_MAX];
void *priv;
uint32_t ep_cnt;
uint32_t class;
uint32_t speed;
uint32_t addr;
uint32_t mps0;
uint32_t port;
uint16_t intf_num;
};
#define DEVICE_KEYBOARD 1
#define DEVICE_MOUSE 2
#define DEVICE_DISK 3
#define DEVICE_HUB 4
/* Structure in sync with FORTH code */
struct slof_usb_dev {
void *udev;
uint32_t port;
uint32_t addr;
uint32_t hcitype;
uint32_t num;
uint32_t devtype;
} __attribute__((packed));
enum USB_PIPE_DIR {
USB_PIPE_OUT = 0,
USB_PIPE_IN,
};
struct usb_pipe {
struct usb_dev *dev;
struct usb_pipe *next;
uint32_t type;
uint32_t speed;
uint32_t dir;
uint16_t epno;
uint16_t mps;
} __attribute__((packed));
#define REQ_GET_STATUS 0 /* see Table 9-4 */
#define REQ_CLEAR_FEATURE 1
#define REQ_GET_STATE 2 /* HUB specific */
#define REQ_SET_FEATURE 3
#define REQ_SET_ADDRESS 5
#define REQ_GET_DESCRIPTOR 6
#define REQ_SET_DESCRIPTOR 7
#define REQ_GET_CONFIGURATION 8
#define REQ_SET_CONFIGURATION 9
#define REQ_GET_INTERFACE 10
#define REQ_SET_INTERFACE 11
#define REQ_SYNCH_FRAME 12
#define FEATURE_DEVICE_REMOTE_WAKEUP 1
#define FEATURE_ENDPOINT_HALT 0
#define REQT_REC_DEVICE 0
#define REQT_REC_INTERFACE 1
#define REQT_REC_EP 2
#define REQT_REC_OTHER 3
#define REQT_TYPE_STANDARD (0 << 5)
#define REQT_TYPE_CLASS (1 << 5)
#define REQT_TYPE_VENDOR (2 << 5)
#define REQT_TYPE_RSRVD (3 << 5)
#define REQT_DIR_OUT (0 << 7) /* host -> device */
#define REQT_DIR_IN (1 << 7) /* device -> host */
#define DESCR_TYPE_DEVICE 1 /* see Table 9-5 */
#define DESCR_TYPE_CONFIGURATION 2
#define DESCR_TYPE_STRING 3
#define DESCR_TYPE_INTERFACE 4
#define DESCR_TYPE_ENDPOINT 5
#define DESCR_TYPE_HUB 0x29 /* Class Descriptor HUB */
#define DESCR_TYPE_HID 0x21 /* Class Descriptor HID */
#define DESCR_TYPE_REPORT 0x22 /* Class Descriptor HID */
#define DESCR_TYPE_PHYSICAL 0x23 /* Class Descriptor HID */
struct usb_dev_req {
uint8_t bmRequestType; /* direction, recipient */
uint8_t bRequest; /* see spec: Table 9-3 */
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength; /* number of bytes to transfer */
} __attribute__((packed));
/* Standard Device Descriptor (18 Bytes) */
/*******************************************/
struct usb_dev_descr {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} __attribute__((packed));
/*******************************************/
/* Standard Configuration Descriptor */
/*******************************************/
struct usb_dev_config_descr {
uint8_t bLength; /* size of descriptor */
uint8_t bDescriptorType; /* Type = 2 */
uint16_t wTotalLength; /* total returned data */
uint8_t bNumInterfaces; /* interfaces supported by this config */
uint8_t bConfigurationValue; /* Configuration-ID for SetConfiguration */
uint8_t iConfiguration; /* index of string descriptor */
uint8_t bmAttributes; /* configuration characteristics */
uint8_t bMaxPower; /* in 2mA units */
} __attribute__((packed));
/*******************************************/
/* Standard Interface Descriptor */
/*******************************************/
struct usb_dev_intf_descr {
uint8_t bLength; /* size of descriptor */
uint8_t bDescriptorType; /* Type = 4 */
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol; /* protocol code */
uint8_t iInterface; /* index to string descriptor */
} __attribute__((packed));
/*******************************************/
/* HUB-Class Descriptor */
/*******************************************/
struct usb_dev_hub_descr {
uint8_t bLength; /* size of complete descriptor */
uint8_t bDescriptorType; /* type = 0x29 for HUB */
uint8_t bNbrPorts; /* number of downstream ports */
uint8_t wHubCharacteristics; /* mode bits 7..0 */
uint8_t reserved; /* mode bits 15..8 */
uint8_t bPwrOn2PwrGood; /* in 2ms units */
uint8_t bHubContrCurrent; /* current requirement in mA */
uint8_t DeviceTable; /* length depends on number of ports */
} __attribute__((packed));
/*******************************************/
/* HID-Class Descriptor */
/*******************************************/
struct usb_dev_hid_descr {
uint8_t bLength; /* size of this descriptor */
uint8_t bDescriptorType; /* type = 0x21 for HID */
uint16_t bcdHID; /* Sample: 0x0102 for 2.01 */
uint8_t bCountryCode; /* Hardware target country */
uint8_t bNumDescriptors; /* Number of HID class descr. */
uint8_t bReportType; /* Report Descriptor Type */
uint16_t wReportLength; /* Total Length of Report Descr. */
} __attribute__((packed));
struct usb_hcd_ops {
const char *name;
void (*init)(struct usb_hcd_dev *);
void (*exit)(struct usb_hcd_dev *);
void (*detect)(void);
void (*disconnect)(void);
int (*send_ctrl)(struct usb_pipe *pipe, struct usb_dev_req *req, void *data);
struct usb_pipe* (*get_pipe)(struct usb_dev *dev, struct usb_ep_descr *ep,
char *buf, size_t len);
int (*transfer_bulk)(struct usb_pipe *pipe, void *td, void *td_phys, void *data, int size);
void (*put_pipe)(struct usb_pipe *);
int (*poll_intr)(struct usb_pipe *, uint8_t *);
struct usb_hcd_ops *next;
unsigned int usb_type;
};
#define usb_get_intf_class(x) ((x & 0x00FF0000) >> 16)
extern void usb_hcd_register(struct usb_hcd_ops *ops);
extern struct usb_pipe *usb_get_pipe(struct usb_dev *dev, struct usb_ep_descr *ep,
char *buf, size_t len);
extern void usb_put_pipe(struct usb_pipe *pipe);
extern int usb_poll_intr(struct usb_pipe *pipe, uint8_t *buf);
extern int usb_send_ctrl(struct usb_pipe *pipe, struct usb_dev_req *req, void *data);
extern struct usb_dev *usb_devpool_get(void);
extern void usb_devpool_put(struct usb_dev *);
extern int usb_setup_new_device(struct usb_dev *dev, unsigned int port);
extern void usb_slof_populate_new_device(struct usb_dev *dev);
extern int usb_dev_populate_pipe(struct usb_dev *dev, struct usb_ep_descr *ep,
void *buf, size_t len);
extern int usb_hid_kbd_init(struct usb_dev *dev);
extern int usb_hid_kbd_exit(struct usb_dev *dev);
extern int usb_msc_reset(struct usb_dev *dev);
extern void usb_msc_resetrecovery(struct usb_dev *dev);
#endif
|