summaryrefslogtreecommitdiffstats
path: root/qemu/roms/SLOF/lib/libusb/usb-core.h
blob: a35df3485e1d831704258488909c49797162b76f (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
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