1 /*****************************************************************************
2  * Copyright (c) 2013 IBM Corporation
3  * All rights reserved.
4  * This program and the accompanying materials
5  * are made available under the terms of the BSD License
6  * which accompanies this distribution, and is available at
7  * http://www.opensource.org/licenses/bsd-license.php
8  *
9  * Contributors:
10  *     IBM Corporation - initial implementation
11  *****************************************************************************/
12 
13 #ifndef __USB_CORE_H
14 #define __USB_CORE_H
15 
16 #include <stdio.h>
17 #include <stdbool.h>
18 #include "helpers.h"
19 #include "usb.h"
20 #include "tools.h"
21 
22 enum usb_hcd_type {
23 	USB_OHCI = 1,
24 	USB_EHCI = 2,
25 	USB_XHCI = 3,
26 };
27 
28 struct usb_hcd_dev;
29 
30 struct usb_hcd_dev {
31 	void *base;
32 	long type;
33 	long num;
34 	struct usb_hcd_ops *ops;
35 	void *priv; /* hcd owned structure */
36 	long nextaddr; /* address for devices */
37 };
38 
39 struct usb_pipe;
40 
41 /*******************************************/
42 /* Standard Endpoint Descriptor            */
43 /*******************************************/
44 /* bmAttributes */
45 #define USB_EP_TYPE_MASK          0x03
46 #define USB_EP_TYPE_CONTROL       0
47 #define USB_EP_TYPE_ISOC          1
48 #define USB_EP_TYPE_BULK          2
49 #define USB_EP_TYPE_INTR          3
50 
51 struct usb_ep_descr {
52 	uint8_t		bLength;		/* size of descriptor */
53 	uint8_t		bDescriptorType;	/* Type = 5 */
54 	uint8_t		bEndpointAddress;
55 	uint8_t		bmAttributes;
56 	uint16_t	wMaxPacketSize;
57 	uint8_t		bInterval;
58 } __attribute__((packed, aligned(4)));
59 
60 #define	DEV_HID_KEYB            0x030101	/* class=HIB,	protocol=Keyboard */
61 #define	DEV_HID_MOUSE           0x030102	/* class=HIB,	protocol=Mouse */
62 #define	DEV_HUB                 0x090000	/* class=HUB, subclass, protocol */
63 #define	DEV_MASS_RBC            0x080150	/* MassStorage, RBC, Bulk */
64 #define	DEV_CDROM_ATAPI         0x080250	/* MassStorage, SFF-8020i , Bulk */
65 #define	DEV_MASS_FLOPPY         0x080450	/* MassStorage, UFI, Bulk */
66 #define	DEV_MASS_ATAPI          0x080550	/* MassStorage, SFF-8070i , Bulk */
67 #define	DEV_MASS_SCSI           0x080650	/* MassStorage, SCSI, Bulk */
68 
69 enum USB_SPEED_TYPE {
70 	USB_LOW_SPEED = 0,
71 	USB_FULL_SPEED = 1,
72 	USB_HIGH_SPEED = 2,
73 	USB_SUPER_SPEED = 3,
74 };
75 
76 /* Max number of endpoints supported in a device */
77 #define USB_DEV_EP_MAX 4
78 #define USB_TIMEOUT    5000 /* 5 sec usb timeout */
79 
80 struct usb_dev {
81 	struct usb_dev     *next;
82 	struct usb_dev     *hub;
83 	struct usb_hcd_dev *hcidev;
84 	struct usb_pipe    *intr;
85 	struct usb_pipe    *control;
86 	struct usb_pipe    *bulk_in;
87 	struct usb_pipe    *bulk_out;
88 	struct usb_ep_descr ep[USB_DEV_EP_MAX];
89 	void *priv;
90 	uint32_t ep_cnt;
91 	uint32_t class;
92 	uint32_t speed;
93 	uint32_t addr;
94 	uint32_t mps0;
95 	uint32_t port;
96 	uint16_t intf_num;
97 };
98 
99 #define DEVICE_KEYBOARD    1
100 #define DEVICE_MOUSE       2
101 #define DEVICE_DISK        3
102 #define DEVICE_HUB         4
103 
104 /* Structure in sync with FORTH code */
105 struct slof_usb_dev {
106 	void     *udev;
107 	uint32_t port;
108 	uint32_t addr;
109 	uint32_t hcitype;
110 	uint32_t num;
111 	uint32_t devtype;
112 } __attribute__((packed));
113 
114 enum USB_PIPE_DIR {
115 	USB_PIPE_OUT = 0,
116 	USB_PIPE_IN,
117 };
118 
119 struct usb_pipe {
120 	struct usb_dev *dev;
121 	struct usb_pipe *next;
122 	uint32_t type;
123 	uint32_t speed;
124 	uint32_t dir;
125 	uint16_t epno;
126 	uint16_t mps;
127 } __attribute__((packed));
128 
129 #define	REQ_GET_STATUS		     0	/* see Table 9-4 */
130 #define	REQ_CLEAR_FEATURE	     1
131 #define	REQ_GET_STATE		     2	/* HUB specific */
132 #define	REQ_SET_FEATURE		     3
133 #define	REQ_SET_ADDRESS		     5
134 #define	REQ_GET_DESCRIPTOR	     6
135 #define	REQ_SET_DESCRIPTOR	     7
136 #define	REQ_GET_CONFIGURATION	     8
137 #define	REQ_SET_CONFIGURATION	     9
138 #define	REQ_GET_INTERFACE	     10
139 #define	REQ_SET_INTERFACE	     11
140 #define	REQ_SYNCH_FRAME              12
141 
142 #define FEATURE_DEVICE_REMOTE_WAKEUP 1
143 #define FEATURE_ENDPOINT_HALT        0
144 
145 #define REQT_REC_DEVICE              0
146 #define REQT_REC_INTERFACE           1
147 #define REQT_REC_EP                  2
148 #define REQT_REC_OTHER               3
149 #define REQT_TYPE_STANDARD           (0 << 5)
150 #define REQT_TYPE_CLASS              (1 << 5)
151 #define REQT_TYPE_VENDOR             (2 << 5)
152 #define REQT_TYPE_RSRVD              (3 << 5)
153 #define REQT_DIR_OUT                 (0 << 7) /* host -> device */
154 #define REQT_DIR_IN                  (1 << 7) /* device -> host */
155 
156 #define	DESCR_TYPE_DEVICE		1	/* see Table 9-5 */
157 #define	DESCR_TYPE_CONFIGURATION	2
158 #define	DESCR_TYPE_STRING		3
159 #define	DESCR_TYPE_INTERFACE		4
160 #define	DESCR_TYPE_ENDPOINT		5
161 #define	DESCR_TYPE_HUB			0x29	/* Class Descriptor HUB */
162 #define DESCR_TYPE_HID			0x21	/* Class Descriptor HID */
163 #define DESCR_TYPE_REPORT		0x22	/* Class Descriptor HID */
164 #define DESCR_TYPE_PHYSICAL		0x23	/* Class Descriptor HID */
165 
166 struct usb_dev_req {
167 	uint8_t		bmRequestType;		/* direction, recipient */
168 	uint8_t		bRequest;		/* see spec: Table 9-3 */
169 	uint16_t	wValue;
170 	uint16_t	wIndex;
171 	uint16_t	wLength;		/* number of bytes to transfer */
172 } __attribute__((packed));
173 
174 /* Standard Device Descriptor (18 Bytes)   */
175 /*******************************************/
176 struct usb_dev_descr {
177 	uint8_t		bLength;
178 	uint8_t		bDescriptorType;
179 	uint16_t	bcdUSB;
180 	uint8_t		bDeviceClass;
181 	uint8_t		bDeviceSubClass;
182 	uint8_t		bDeviceProtocol;
183 	uint8_t		bMaxPacketSize0;
184 	uint16_t	idVendor;
185 	uint16_t	idProduct;
186 	uint16_t	bcdDevice;
187 	uint8_t		iManufacturer;
188 	uint8_t		iProduct;
189 	uint8_t		iSerialNumber;
190 	uint8_t		bNumConfigurations;
191 } __attribute__((packed));
192 
193 /*******************************************/
194 /* Standard Configuration Descriptor       */
195 /*******************************************/
196 struct usb_dev_config_descr {
197 	uint8_t		bLength;		/* size of descriptor */
198 	uint8_t		bDescriptorType;	/* Type = 2 */
199 	uint16_t	wTotalLength;		/* total returned data */
200 	uint8_t		bNumInterfaces;		/* interfaces supported by this config */
201 	uint8_t		bConfigurationValue;	/* Configuration-ID for SetConfiguration */
202 	uint8_t		iConfiguration;		/* index of string descriptor */
203 	uint8_t		bmAttributes;		/* configuration characteristics */
204 	uint8_t		bMaxPower;		/* in 2mA units */
205 } __attribute__((packed));
206 
207 /*******************************************/
208 /* Standard Interface Descriptor */
209 /*******************************************/
210 struct usb_dev_intf_descr {
211 	uint8_t		bLength;		/* size of descriptor */
212 	uint8_t		bDescriptorType;	/* Type = 4 */
213 	uint8_t		bInterfaceNumber;
214 	uint8_t		bAlternateSetting;
215 	uint8_t		bNumEndpoints;
216 	uint8_t		bInterfaceClass;
217 	uint8_t		bInterfaceSubClass;
218 	uint8_t		bInterfaceProtocol;	/* protocol code */
219 	uint8_t		iInterface;		/* index to string descriptor */
220 } __attribute__((packed));
221 
222 /*******************************************/
223 /* HUB-Class Descriptor                    */
224 /*******************************************/
225 struct usb_dev_hub_descr {
226 	uint8_t		bLength;		/* size of complete descriptor */
227 	uint8_t		bDescriptorType;	/* type = 0x29 for HUB */
228 	uint8_t		bNbrPorts;		/* number of downstream ports */
229 	uint8_t		wHubCharacteristics;	/* mode bits	7..0 */
230 	uint8_t		reserved;		/* mode bits 15..8 */
231 	uint8_t		bPwrOn2PwrGood;		/* in 2ms units */
232 	uint8_t		bHubContrCurrent;	/* current requirement in mA */
233 	uint8_t		DeviceTable;	        /* length depends on number of ports */
234 } __attribute__((packed));
235 
236 /*******************************************/
237 /* HID-Class Descriptor                    */
238 /*******************************************/
239 struct usb_dev_hid_descr {
240 	uint8_t		bLength;		/* size of this descriptor */
241 	uint8_t		bDescriptorType;	/* type = 0x21 for HID     */
242 	uint16_t	bcdHID;			/* Sample: 0x0102 for 2.01  */
243 	uint8_t		bCountryCode;		/* Hardware target country */
244 	uint8_t		bNumDescriptors;	/* Number of HID class descr. */
245 	uint8_t		bReportType;		/* Report Descriptor Type */
246 	uint16_t	wReportLength;		/* Total Length of Report Descr. */
247 } __attribute__((packed));
248 
249 struct usb_hcd_ops {
250 	const char *name;
251 	void (*init)(struct usb_hcd_dev *);
252 	void (*exit)(struct usb_hcd_dev *);
253 	void (*detect)(void);
254 	void (*disconnect)(void);
255 	int  (*send_ctrl)(struct usb_pipe *pipe, struct usb_dev_req *req, void *data);
256 	struct usb_pipe* (*get_pipe)(struct usb_dev *dev, struct usb_ep_descr *ep,
257 				char *buf, size_t len);
258 	int  (*transfer_bulk)(struct usb_pipe *pipe, void *td, void *td_phys, void *data, int size);
259 	void (*put_pipe)(struct usb_pipe *);
260 	int (*poll_intr)(struct usb_pipe *, uint8_t *);
261 	struct usb_hcd_ops *next;
262 	unsigned int usb_type;
263 };
264 
265 #define usb_get_intf_class(x) ((x & 0x00FF0000) >> 16)
266 
267 extern void usb_hcd_register(struct usb_hcd_ops *ops);
268 extern struct usb_pipe *usb_get_pipe(struct usb_dev *dev, struct usb_ep_descr *ep,
269 				char *buf, size_t len);
270 extern void usb_put_pipe(struct usb_pipe *pipe);
271 extern int usb_poll_intr(struct usb_pipe *pipe, uint8_t *buf);
272 extern int usb_send_ctrl(struct usb_pipe *pipe, struct usb_dev_req *req, void *data);
273 extern struct usb_dev *usb_devpool_get(void);
274 extern void usb_devpool_put(struct usb_dev *);
275 extern int usb_setup_new_device(struct usb_dev *dev, unsigned int port);
276 extern void usb_slof_populate_new_device(struct usb_dev *dev);
277 extern int usb_dev_populate_pipe(struct usb_dev *dev, struct usb_ep_descr *ep,
278 				void *buf, size_t len);
279 extern int usb_hid_kbd_init(struct usb_dev *dev);
280 extern int usb_hid_kbd_exit(struct usb_dev *dev);
281 extern int usb_msc_reset(struct usb_dev *dev);
282 extern void usb_msc_resetrecovery(struct usb_dev *dev);
283 #endif
284