xref: /rk3399_rockchip-uboot/include/usbdevice.h (revision 2731b9a86685190d26b1883f27afda5ac8e1a313)
1*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
2*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * (C) Copyright 2003
3*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Gerry Hamel, geh@ti.com, Texas Instruments
4*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
5*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Based on linux/drivers/usbd/usbd.h
6*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
7*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Copyright (c) 2000, 2001, 2002 Lineo
8*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Copyright (c) 2001 Hewlett Packard
9*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
10*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * By:
11*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	Stuart Lynne <sl@lineo.com>,
12*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	Tom Rushworth <tbr@lineo.com>,
13*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	Bruce Balden <balden@lineo.com>
14*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
15*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * This program is free software; you can redistribute it and/or modify
16*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * it under the terms of the GNU General Public License as published by
17*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * the Free Software Foundation; either version 2 of the License, or
18*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * (at your option) any later version.
19*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
20*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * This program is distributed in the hope that it will be useful,
21*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
23*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * GNU General Public License for more details.
24*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
25*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * You should have received a copy of the GNU General Public License
26*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * along with this program; if not, write to the Free Software
27*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
29*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
30*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
31*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef __USBDCORE_H__
32*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define __USBDCORE_H__
33*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
34*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #include <common.h>
35*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #include "usbdescriptors.h"
36*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
37*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
38*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define MAX_URBS_QUEUED 5
39*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
40*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
41*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #if 1
42*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define usberr(fmt,args...) serial_printf("ERROR: %s(), %d: "fmt"\n",__FUNCTION__,__LINE__,##args)
43*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #else
44*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define usberr(fmt,args...) do{}while(0)
45*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
46*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
47*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #if 0
48*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define usbdbg(fmt,args...) serial_printf("debug: %s(), %d: "fmt"\n",__FUNCTION__,__LINE__,##args)
49*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #else
50*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define usbdbg(fmt,args...) do{}while(0)
51*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
52*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
53*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #if 0
54*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define usbinfo(fmt,args...) serial_printf("info: %s(), %d: "fmt"\n",__FUNCTION__,__LINE__,##args)
55*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #else
56*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define usbinfo(fmt,args...) do{}while(0)
57*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
58*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
59*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef le16_to_cpu
60*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define le16_to_cpu(x)	(x)
61*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
62*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
63*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef inb
64*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define inb(p)	     (*(volatile u8*)(p))
65*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
66*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
67*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef outb
68*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define outb(val,p)  (*(volatile u8*)(p) = (val))
69*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
70*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
71*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef inw
72*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define inw(p)	     (*(volatile u16*)(p))
73*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
74*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
75*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef outw
76*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define outw(val,p)  (*(volatile u16*)(p) = (val))
77*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
78*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
79*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef inl
80*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define inl(p)	     (*(volatile u32*)(p))
81*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
82*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
83*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef outl
84*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define outl(val,p)  (*(volatile u32*)(p) = (val))
85*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
86*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
87*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef insw
88*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define insw(p,to,len)	   mmio_insw(p,to,len)
89*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
90*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
91*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef outsw
92*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define outsw(p,from,len)  mmio_outsw(p,from,len)
93*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
94*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
95*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef insb
96*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define insb(p,to,len)	   mmio_insb(p,to,len)
97*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
98*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
99*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef mmio_insw
100*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define mmio_insw(r,b,l)	({	int __i ;  \
101*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					u16 *__b2;  \
102*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					__b2 = (u16 *) b;  \
103*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					for (__i = 0; __i < l; __i++) {	 \
104*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					  *(__b2 + __i) = inw(r);  \
105*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					};  \
106*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 				})
107*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
108*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
109*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef mmio_outsw
110*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define mmio_outsw(r,b,l)	({	int __i; \
111*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					u16 *__b2; \
112*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					__b2 = (u16 *) b; \
113*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					for (__i = 0; __i < l; __i++) { \
114*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					    outw( *(__b2 + __i), r); \
115*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					} \
116*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 				})
117*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
118*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
119*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef mmio_insb
120*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define mmio_insb(r,b,l)	({	int __i ;  \
121*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					u8 *__b2;  \
122*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					__b2 = (u8 *) b;  \
123*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					for (__i = 0; __i < l; __i++) {	 \
124*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					  *(__b2 + __i) = inb(r);  \
125*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 					};  \
126*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 				})
127*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
128*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
129*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
130*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Structure member address manipulation macros.
131*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * These are used by client code (code using the urb_link routines), since
132*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * the urb_link structure is embedded in the client data structures.
133*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
134*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Note: a macro offsetof equivalent to member_offset is defined in stddef.h
135*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	 but this is kept here for the sake of portability.
136*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
137*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * p2surround returns a pointer to the surrounding structure given
138*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * type of the surrounding structure, the name memb of the structure
139*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * member pointed at by ptr.  For example, if you have:
140*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
141*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	struct foo {
142*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	    int x;
143*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	    float y;
144*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	    char z;
145*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	} thingy;
146*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
147*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	char *cp = &thingy.z;
148*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
149*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * then
150*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
151*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	&thingy == p2surround(struct foo, z, cp)
152*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
153*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Clear?
154*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
155*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define _cv_(ptr)		  ((char*)(void*)(ptr))
156*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define member_offset(type,memb)  (_cv_(&(((type*)0)->memb))-(char*)0)
157*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define p2surround(type,memb,ptr) ((type*)(void*)(_cv_(ptr)-member_offset(type,memb)))
158*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
159*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct urb;
160*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
161*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance;
162*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_interface_instance;
163*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_configuration_instance;
164*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_device_instance;
165*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_bus_instance;
166*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
167*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
168*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Device and/or Interface Class codes
169*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
170*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_CLASS_PER_INTERFACE		0	/* for DeviceClass */
171*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_CLASS_AUDIO			1
172*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_CLASS_COMM			2
173*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_CLASS_HID			3
174*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_CLASS_PHYSICAL		5
175*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_CLASS_PRINTER		7
176*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_CLASS_MASS_STORAGE		8
177*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_CLASS_HUB			9
178*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_CLASS_DATA			10
179*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_CLASS_APP_SPEC		0xfe
180*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_CLASS_VENDOR_SPEC		0xff
181*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
182*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
183*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * USB types
184*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
185*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_TYPE_STANDARD		(0x00 << 5)
186*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_TYPE_CLASS			(0x01 << 5)
187*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_TYPE_VENDOR			(0x02 << 5)
188*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_TYPE_RESERVED		(0x03 << 5)
189*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
190*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
191*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * USB recipients
192*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
193*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_RECIP_DEVICE		0x00
194*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_RECIP_INTERFACE		0x01
195*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_RECIP_ENDPOINT		0x02
196*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_RECIP_OTHER			0x03
197*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
198*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
199*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * USB directions
200*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
201*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DIR_OUT			0
202*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DIR_IN			0x80
203*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
204*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
205*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Descriptor types
206*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
207*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_DEVICE			0x01
208*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_CONFIG			0x02
209*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_STRING			0x03
210*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_INTERFACE		0x04
211*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_ENDPOINT			0x05
212*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
213*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_HID			(USB_TYPE_CLASS | 0x01)
214*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_REPORT			(USB_TYPE_CLASS | 0x02)
215*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_PHYSICAL			(USB_TYPE_CLASS | 0x03)
216*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_HUB			(USB_TYPE_CLASS | 0x09)
217*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
218*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
219*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Descriptor sizes per descriptor type
220*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
221*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_DEVICE_SIZE		18
222*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_CONFIG_SIZE		9
223*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_INTERFACE_SIZE		9
224*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_ENDPOINT_SIZE		7
225*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_ENDPOINT_AUDIO_SIZE	9	/* Audio extension */
226*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_HUB_NONVAR_SIZE		7
227*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DT_HID_SIZE			9
228*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
229*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
230*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Endpoints
231*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
232*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_ENDPOINT_NUMBER_MASK	0x0f	/* in bEndpointAddress */
233*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_ENDPOINT_DIR_MASK		0x80
234*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
235*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_ENDPOINT_XFERTYPE_MASK	0x03	/* in bmAttributes */
236*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_ENDPOINT_XFER_CONTROL	0
237*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_ENDPOINT_XFER_ISOC		1
238*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_ENDPOINT_XFER_BULK		2
239*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_ENDPOINT_XFER_INT		3
240*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
241*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
242*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * USB Packet IDs (PIDs)
243*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
244*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_UNDEF_0			       0xf0
245*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_OUT			       0xe1
246*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_ACK			       0xd2
247*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_DATA0			       0xc3
248*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_PING			       0xb4	/* USB 2.0 */
249*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_SOF			       0xa5
250*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_NYET			       0x96	/* USB 2.0 */
251*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_DATA2			       0x87	/* USB 2.0 */
252*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_SPLIT			       0x78	/* USB 2.0 */
253*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_IN			       0x69
254*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_NAK			       0x5a
255*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_DATA1			       0x4b
256*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_PREAMBLE		       0x3c	/* Token mode */
257*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_ERR			       0x3c	/* USB 2.0: handshake mode */
258*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_SETUP			       0x2d
259*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_STALL			       0x1e
260*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_PID_MDATA			       0x0f	/* USB 2.0 */
261*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
262*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
263*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Standard requests
264*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
265*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_GET_STATUS		0x00
266*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_CLEAR_FEATURE		0x01
267*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_SET_FEATURE		0x03
268*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_SET_ADDRESS		0x05
269*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_GET_DESCRIPTOR		0x06
270*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_SET_DESCRIPTOR		0x07
271*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_GET_CONFIGURATION	0x08
272*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_SET_CONFIGURATION	0x09
273*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_GET_INTERFACE		0x0A
274*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_SET_INTERFACE		0x0B
275*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_SYNCH_FRAME		0x0C
276*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
277*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USBD_DEVICE_REQUESTS(x) (((unsigned int)x <= USB_REQ_SYNCH_FRAME) ? usbd_device_requests[x] : "UNKNOWN")
278*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
279*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
280*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * HID requests
281*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
282*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_GET_REPORT		0x01
283*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_GET_IDLE		0x02
284*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_GET_PROTOCOL		0x03
285*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_SET_REPORT		0x09
286*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_SET_IDLE		0x0A
287*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_SET_PROTOCOL		0x0B
288*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
289*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
290*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
291*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * USB Spec Release number
292*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
293*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
294*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_BCD_VERSION			0x0110
295*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
296*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
297*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
298*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Device Requests	(c.f Table 9-2)
299*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
300*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
301*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_DIRECTION_MASK		0x80
302*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_TYPE_MASK		0x60
303*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_RECIPIENT_MASK		0x1f
304*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
305*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_DEVICE2HOST		0x80
306*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_HOST2DEVICE		0x00
307*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
308*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_TYPE_STANDARD		0x00
309*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_TYPE_CLASS		0x20
310*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_TYPE_VENDOR		0x40
311*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
312*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_RECIPIENT_DEVICE	0x00
313*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_RECIPIENT_INTERFACE	0x01
314*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_RECIPIENT_ENDPOINT	0x02
315*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_REQ_RECIPIENT_OTHER		0x03
316*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
317*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
318*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * get status bits
319*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
320*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
321*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_STATUS_SELFPOWERED		0x01
322*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_STATUS_REMOTEWAKEUP		0x02
323*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
324*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_STATUS_HALT			0x01
325*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
326*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
327*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * descriptor types
328*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
329*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
330*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DESCRIPTOR_TYPE_DEVICE			0x01
331*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DESCRIPTOR_TYPE_CONFIGURATION		0x02
332*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DESCRIPTOR_TYPE_STRING			0x03
333*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DESCRIPTOR_TYPE_INTERFACE			0x04
334*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DESCRIPTOR_TYPE_ENDPOINT			0x05
335*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER		0x06
336*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION	0x07
337*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DESCRIPTOR_TYPE_INTERFACE_POWER		0x08
338*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DESCRIPTOR_TYPE_HID				0x21
339*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DESCRIPTOR_TYPE_REPORT			0x22
340*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
341*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USBD_DEVICE_DESCRIPTORS(x) (((unsigned int)x <= USB_DESCRIPTOR_TYPE_INTERFACE_POWER) ? \
342*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 		usbd_device_descriptors[x] : "UNKNOWN")
343*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
344*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
345*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * standard feature selectors
346*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
347*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_ENDPOINT_HALT		0x00
348*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_DEVICE_REMOTE_WAKEUP	0x01
349*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USB_TEST_MODE			0x02
350*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
351*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
352*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /* USB Requests
353*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
354*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
355*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
356*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_device_request {
357*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u8 bmRequestType;
358*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u8 bRequest;
359*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u16 wValue;
360*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u16 wIndex;
361*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u16 wLength;
362*2731b9a8SJean-Christophe PLAGNIOL-VILLARD } __attribute__ ((packed));
363*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
364*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
365*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /* USB Status
366*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
367*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
368*2731b9a8SJean-Christophe PLAGNIOL-VILLARD typedef enum urb_send_status {
369*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	SEND_IN_PROGRESS,
370*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	SEND_FINISHED_OK,
371*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	SEND_FINISHED_ERROR,
372*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	RECV_READY,
373*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	RECV_OK,
374*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	RECV_ERROR
375*2731b9a8SJean-Christophe PLAGNIOL-VILLARD } urb_send_status_t;
376*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
377*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
378*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Device State (c.f USB Spec 2.0 Figure 9-1)
379*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
380*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * What state the usb device is in.
381*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
382*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Note the state does not change if the device is suspended, we simply set a
383*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * flag to show that it is suspended.
384*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
385*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
386*2731b9a8SJean-Christophe PLAGNIOL-VILLARD typedef enum usb_device_state {
387*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	STATE_INIT,		/* just initialized */
388*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	STATE_CREATED,		/* just created */
389*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	STATE_ATTACHED,		/* we are attached */
390*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	STATE_POWERED,		/* we have seen power indication (electrical bus signal) */
391*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	STATE_DEFAULT,		/* we been reset */
392*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	STATE_ADDRESSED,	/* we have been addressed (in default configuration) */
393*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	STATE_CONFIGURED,	/* we have seen a set configuration device command */
394*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	STATE_UNKNOWN,		/* destroyed */
395*2731b9a8SJean-Christophe PLAGNIOL-VILLARD } usb_device_state_t;
396*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
397*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USBD_DEVICE_STATE(x) (((unsigned int)x <= STATE_UNKNOWN) ? usbd_device_states[x] : "UNKNOWN")
398*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
399*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
400*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Device status
401*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
402*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Overall state
403*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
404*2731b9a8SJean-Christophe PLAGNIOL-VILLARD typedef enum usb_device_status {
405*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	USBD_OPENING,		/* we are currently opening */
406*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	USBD_OK,		/* ok to use */
407*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	USBD_SUSPENDED,		/* we are currently suspended */
408*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	USBD_CLOSING,		/* we are currently closing */
409*2731b9a8SJean-Christophe PLAGNIOL-VILLARD } usb_device_status_t;
410*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
411*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define USBD_DEVICE_STATUS(x) (((unsigned int)x <= USBD_CLOSING) ? usbd_device_status[x] : "UNKNOWN")
412*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
413*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
414*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Device Events
415*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
416*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * These are defined in the USB Spec (c.f USB Spec 2.0 Figure 9-1).
417*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
418*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * There are additional events defined to handle some extra actions we need
419*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * to have handled.
420*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
421*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
422*2731b9a8SJean-Christophe PLAGNIOL-VILLARD typedef enum usb_device_event {
423*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
424*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_UNKNOWN,		/* bi - unknown event */
425*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_INIT,		/* bi  - initialize */
426*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_CREATE,		/* bi  - */
427*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_HUB_CONFIGURED,	/* bi  - bus has been plugged int */
428*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_RESET,		/* bi  - hub has powered our port */
429*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
430*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_ADDRESS_ASSIGNED,	/* ep0 - set address setup received */
431*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_CONFIGURED,	/* ep0 - set configure setup received */
432*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_SET_INTERFACE,	/* ep0 - set interface setup received */
433*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
434*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_SET_FEATURE,	/* ep0 - set feature setup received */
435*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_CLEAR_FEATURE,	/* ep0 - clear feature setup received */
436*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
437*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_DE_CONFIGURED,	/* ep0 - set configure setup received for ?? */
438*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
439*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_BUS_INACTIVE,	/* bi  - bus in inactive (no SOF packets) */
440*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_BUS_ACTIVITY,	/* bi  - bus is active again */
441*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
442*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_POWER_INTERRUPTION,	/* bi  - hub has depowered our port */
443*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_HUB_RESET,	/* bi  - bus has been unplugged */
444*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_DESTROY,		/* bi  - device instance should be destroyed */
445*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
446*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_HOTPLUG,		/* bi  - a hotplug event has occured */
447*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
448*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	DEVICE_FUNCTION_PRIVATE,	/* function - private */
449*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
450*2731b9a8SJean-Christophe PLAGNIOL-VILLARD } usb_device_event_t;
451*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
452*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
453*2731b9a8SJean-Christophe PLAGNIOL-VILLARD typedef struct urb_link {
454*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct urb_link *next;
455*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct urb_link *prev;
456*2731b9a8SJean-Christophe PLAGNIOL-VILLARD } urb_link;
457*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
458*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /* USB Data structure - for passing data around.
459*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
460*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * This is used for both sending and receiving data.
461*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
462*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * The callback function is used to let the function driver know when
463*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * transmitted data has been sent.
464*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
465*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * The callback function is set by the alloc_recv function when an urb is
466*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * allocated for receiving data for an endpoint and used to call the
467*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * function driver to inform it that data has arrived.
468*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
469*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
470*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #define URB_BUF_SIZE 128 /* in linux we'd malloc this, but in u-boot we prefer static data */
471*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct urb {
472*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
473*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct usb_endpoint_instance *endpoint;
474*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct usb_device_instance *device;
475*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
476*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct usb_device_request device_request;	/* contents of received SETUP packet */
477*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
478*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct urb_link link;	/* embedded struct for circular doubly linked list of urbs */
479*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
480*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u8* buffer;
481*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	unsigned int buffer_length;
482*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	unsigned int actual_length;
483*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
484*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	urb_send_status_t status;
485*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int data;
486*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
487*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u16 buffer_data[URB_BUF_SIZE];	/* data received (OUT) or being sent (IN) */
488*2731b9a8SJean-Christophe PLAGNIOL-VILLARD };
489*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
490*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /* Endpoint configuration
491*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
492*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Per endpoint configuration data. Used to track which function driver owns
493*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * an endpoint.
494*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
495*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
496*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance {
497*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int endpoint_address;	/* logical endpoint address */
498*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
499*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* control */
500*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int status;		/* halted */
501*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int state;		/* available for use by bus interface driver */
502*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
503*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* receive side */
504*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct urb_link rcv;	/* received urbs */
505*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct urb_link rdy;	/* empty urbs ready to receive */
506*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct urb *rcv_urb;	/* active urb */
507*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int rcv_attributes;	/* copy of bmAttributes from endpoint descriptor */
508*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int rcv_packetSize;	/* maximum packet size from endpoint descriptor */
509*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int rcv_transferSize;	/* maximum transfer size from function driver */
510*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int rcv_queue;
511*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
512*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* transmit side */
513*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct urb_link tx;	/* urbs ready to transmit */
514*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct urb_link done;	/* transmitted urbs */
515*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct urb *tx_urb;	/* active urb */
516*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int tx_attributes;	/* copy of bmAttributes from endpoint descriptor */
517*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int tx_packetSize;	/* maximum packet size from endpoint descriptor */
518*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int tx_transferSize;	/* maximum transfer size from function driver */
519*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int tx_queue;
520*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
521*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int sent;		/* data already sent */
522*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int last;		/* data sent in last packet XXX do we need this */
523*2731b9a8SJean-Christophe PLAGNIOL-VILLARD };
524*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
525*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_alternate_instance {
526*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct usb_interface_descriptor *interface_descriptor;
527*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
528*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int endpoints;
529*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int *endpoint_transfersize_array;
530*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct usb_endpoint_descriptor **endpoints_descriptor_array;
531*2731b9a8SJean-Christophe PLAGNIOL-VILLARD };
532*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
533*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_interface_instance {
534*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int alternates;
535*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct usb_alternate_instance *alternates_instance_array;
536*2731b9a8SJean-Christophe PLAGNIOL-VILLARD };
537*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
538*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_configuration_instance {
539*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int interfaces;
540*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct usb_configuration_descriptor *configuration_descriptor;
541*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct usb_interface_instance *interface_instance_array;
542*2731b9a8SJean-Christophe PLAGNIOL-VILLARD };
543*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
544*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
545*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /* USB Device Instance
546*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
547*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * For each physical bus interface we create a logical device structure. This
548*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * tracks all of the required state to track the USB HOST's view of the device.
549*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
550*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Keep track of the device configuration for a real physical bus interface,
551*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * this includes the bus interface, multiple function drivers, the current
552*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * configuration and the current state.
553*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
554*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * This will show:
555*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	the specific bus interface driver
556*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	the default endpoint 0 driver
557*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	the configured function driver
558*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	device state
559*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	device status
560*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *	endpoint list
561*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
562*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
563*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_device_instance {
564*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
565*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* generic */
566*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	char *name;
567*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct usb_device_descriptor *device_descriptor;	/* per device descriptor */
568*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
569*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	void (*event) (struct usb_device_instance *device, usb_device_event_t event, int data);
570*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
571*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* Do cdc device specific control requests */
572*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int (*cdc_recv_setup)(struct usb_device_request *request, struct urb *urb);
573*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
574*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* bus interface */
575*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct usb_bus_instance *bus;	/* which bus interface driver */
576*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
577*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* configuration descriptors */
578*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int configurations;
579*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct usb_configuration_instance *configuration_instance_array;
580*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
581*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* device state */
582*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	usb_device_state_t device_state;	/* current USB Device state */
583*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	usb_device_state_t device_previous_state;	/* current USB Device state */
584*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
585*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u8 address;		/* current address (zero is default) */
586*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u8 configuration;	/* current show configuration (zero is default) */
587*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u8 interface;		/* current interface (zero is default) */
588*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u8 alternate;		/* alternate flag */
589*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
590*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	usb_device_status_t status;	/* device status */
591*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
592*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int urbs_queued;	/* number of submitted urbs */
593*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
594*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* Shouldn't need to make this atomic, all we need is a change indicator */
595*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	unsigned long usbd_rxtx_timestamp;
596*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	unsigned long usbd_last_rxtx_timestamp;
597*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
598*2731b9a8SJean-Christophe PLAGNIOL-VILLARD };
599*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
600*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /* Bus Interface configuration structure
601*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
602*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * This is allocated for each configured instance of a bus interface driver.
603*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
604*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * The privdata pointer may be used by the bus interface driver to store private
605*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * per instance state information.
606*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
607*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_bus_instance {
608*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
609*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct usb_device_instance *device;
610*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	struct usb_endpoint_instance *endpoint_array;	/* array of available configured endpoints */
611*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
612*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	int max_endpoints;	/* maximimum number of rx enpoints */
613*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	unsigned char			maxpacketsize;
614*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
615*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	unsigned int serial_number;
616*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	char *serial_number_str;
617*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 	void *privdata;		/* private data for the bus interface */
618*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
619*2731b9a8SJean-Christophe PLAGNIOL-VILLARD };
620*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
621*2731b9a8SJean-Christophe PLAGNIOL-VILLARD extern char *usbd_device_events[];
622*2731b9a8SJean-Christophe PLAGNIOL-VILLARD extern char *usbd_device_states[];
623*2731b9a8SJean-Christophe PLAGNIOL-VILLARD extern char *usbd_device_status[];
624*2731b9a8SJean-Christophe PLAGNIOL-VILLARD extern char *usbd_device_requests[];
625*2731b9a8SJean-Christophe PLAGNIOL-VILLARD extern char *usbd_device_descriptors[];
626*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
627*2731b9a8SJean-Christophe PLAGNIOL-VILLARD void urb_link_init (urb_link * ul);
628*2731b9a8SJean-Christophe PLAGNIOL-VILLARD void urb_detach (struct urb *urb);
629*2731b9a8SJean-Christophe PLAGNIOL-VILLARD urb_link *first_urb_link (urb_link * hd);
630*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct urb *first_urb (urb_link * hd);
631*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct urb *first_urb_detached (urb_link * hd);
632*2731b9a8SJean-Christophe PLAGNIOL-VILLARD void urb_append (urb_link * hd, struct urb *urb);
633*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
634*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct urb *usbd_alloc_urb (struct usb_device_instance *device, struct usb_endpoint_instance *endpoint);
635*2731b9a8SJean-Christophe PLAGNIOL-VILLARD void	    usbd_dealloc_urb (struct urb *urb);
636*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
637*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
638*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * usbd_device_event is used by bus interface drivers to tell the higher layers that
639*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * certain events have taken place.
640*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
641*2731b9a8SJean-Christophe PLAGNIOL-VILLARD void usbd_device_event_irq (struct usb_device_instance *conf, usb_device_event_t, int);
642*2731b9a8SJean-Christophe PLAGNIOL-VILLARD void usbd_device_event (struct usb_device_instance *conf, usb_device_event_t, int);
643*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
644*2731b9a8SJean-Christophe PLAGNIOL-VILLARD /* descriptors
645*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
646*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Various ways of finding descriptors based on the current device and any
647*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  * possible configuration / interface / endpoint for it.
648*2731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
649*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_configuration_descriptor *usbd_device_configuration_descriptor (struct usb_device_instance *, int, int);
650*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_function_instance *usbd_device_function_instance (struct usb_device_instance *, unsigned int);
651*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_interface_instance *usbd_device_interface_instance (struct usb_device_instance *, int, int, int);
652*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_alternate_instance *usbd_device_alternate_instance (struct usb_device_instance *, int, int, int, int);
653*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_interface_descriptor *usbd_device_interface_descriptor (struct usb_device_instance *, int, int, int, int);
654*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor_index (struct usb_device_instance *, int, int, int, int, int);
655*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_class_descriptor *usbd_device_class_descriptor_index (struct usb_device_instance *, int, int, int, int, int);
656*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_class_report_descriptor *usbd_device_class_report_descriptor_index( struct usb_device_instance *, int , int , int , int , int );
657*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor (struct usb_device_instance *, int, int, int, int, int);
658*2731b9a8SJean-Christophe PLAGNIOL-VILLARD int				usbd_device_endpoint_transfersize (struct usb_device_instance *, int, int, int, int, int);
659*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_string_descriptor *usbd_get_string (u8);
660*2731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_instance *, int);
661*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
662*2731b9a8SJean-Christophe PLAGNIOL-VILLARD int usbd_endpoint_halted (struct usb_device_instance *device, int endpoint);
663*2731b9a8SJean-Christophe PLAGNIOL-VILLARD void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad);
664*2731b9a8SJean-Christophe PLAGNIOL-VILLARD void usbd_tx_complete (struct usb_endpoint_instance *endpoint);
665*2731b9a8SJean-Christophe PLAGNIOL-VILLARD 
666*2731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
667