These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / drivers / usb / usbhub.h
1 #ifndef _USBHUB_H
2 #define _USBHUB_H
3
4 /** @file
5  *
6  * USB hubs
7  *
8  */
9
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
12 #include <ipxe/usb.h>
13 #include <ipxe/list.h>
14 #include <ipxe/process.h>
15
16 /** Request recipient is a port */
17 #define USB_HUB_RECIP_PORT ( 3 << 0 )
18
19 /** A basic USB hub descriptor */
20 struct usb_hub_descriptor_basic {
21         /** Descriptor header */
22         struct usb_descriptor_header header;
23         /** Number of ports */
24         uint8_t ports;
25         /** Characteristics */
26         uint16_t characteristics;
27         /** Power-on delay (in 2ms intervals */
28         uint8_t delay;
29         /** Controller current (in mA) */
30         uint8_t current;
31 } __attribute__ (( packed ));
32
33 /** A basic USB hub descriptor */
34 #define USB_HUB_DESCRIPTOR 41
35
36 /** An enhanced USB hub descriptor */
37 struct usb_hub_descriptor_enhanced {
38         /** Basic USB hub descriptor */
39         struct usb_hub_descriptor_basic basic;
40         /** Header decode latency */
41         uint8_t latency;
42         /** Maximum delay */
43         uint16_t delay;
44         /** Removable device bitmask */
45         uint16_t removable;
46 } __attribute__ (( packed ));
47
48 /** An enhanced USB hub descriptor */
49 #define USB_HUB_DESCRIPTOR_ENHANCED 42
50
51 /** A USB hub descriptor */
52 union usb_hub_descriptor {
53         /** Descriptor header */
54         struct usb_descriptor_header header;
55         /** Basic hub descriptor */
56         struct usb_hub_descriptor_basic basic;
57         /** Enhanced hub descriptor */
58         struct usb_hub_descriptor_enhanced enhanced;
59 } __attribute__ (( packed ));
60
61 /** Port status */
62 struct usb_hub_port_status {
63         /** Current status */
64         uint16_t current;
65         /** Changed status */
66         uint16_t changed;
67 } __attribute__ (( packed ));
68
69 /** Current connect status feature */
70 #define USB_HUB_PORT_CONNECTION 0
71
72 /** Port enabled/disabled feature */
73 #define USB_HUB_PORT_ENABLE 1
74
75 /** Port reset feature */
76 #define USB_HUB_PORT_RESET 4
77
78 /** Port power feature */
79 #define USB_HUB_PORT_POWER 8
80
81 /** Low-speed device attached */
82 #define USB_HUB_PORT_LOW_SPEED 9
83
84 /** High-speed device attached */
85 #define USB_HUB_PORT_HIGH_SPEED 10
86
87 /** Connect status changed */
88 #define USB_HUB_C_PORT_CONNECTION 16
89
90 /** Port enable/disable changed */
91 #define USB_HUB_C_PORT_ENABLE 17
92
93 /** Suspend changed */
94 #define USB_HUB_C_PORT_SUSPEND 18
95
96 /** Over-current indicator changed */
97 #define USB_HUB_C_PORT_OVER_CURRENT 19
98
99 /** Reset changed */
100 #define USB_HUB_C_PORT_RESET 20
101
102 /** Link state changed */
103 #define USB_HUB_C_PORT_LINK_STATE 25
104
105 /** Configuration error */
106 #define USB_HUB_C_PORT_CONFIG_ERROR 26
107
108 /** Calculate feature from change bit number */
109 #define USB_HUB_C_FEATURE( bit ) ( 16 + (bit) )
110
111 /** USB features */
112 #define USB_HUB_FEATURES                                                \
113         ( ( 1 << USB_HUB_C_PORT_CONNECTION ) |                          \
114           ( 1 << USB_HUB_C_PORT_ENABLE ) |                              \
115           ( 1 << USB_HUB_C_PORT_SUSPEND ) |                             \
116           ( 1 << USB_HUB_C_PORT_OVER_CURRENT ) |                        \
117           ( 1 << USB_HUB_C_PORT_RESET ) )
118
119 /** USB features for enhanced hubs */
120 #define USB_HUB_FEATURES_ENHANCED                                       \
121         ( ( 1 << USB_HUB_C_PORT_CONNECTION ) |                          \
122           ( 1 << USB_HUB_C_PORT_OVER_CURRENT ) |                        \
123           ( 1 << USB_HUB_C_PORT_RESET ) |                               \
124           ( 1 << USB_HUB_C_PORT_LINK_STATE ) |                          \
125           ( 1 << USB_HUB_C_PORT_CONFIG_ERROR ) )
126
127 /** Set hub depth */
128 #define USB_HUB_SET_HUB_DEPTH                                           \
129         ( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE |             \
130           USB_REQUEST_TYPE ( 12 ) )
131
132 /** Clear transaction translator buffer */
133 #define USB_HUB_CLEAR_TT_BUFFER                                         \
134         ( USB_DIR_OUT | USB_TYPE_CLASS | USB_HUB_RECIP_PORT |           \
135           USB_REQUEST_TYPE ( 8 ) )
136
137 /**
138  * Get hub descriptor
139  *
140  * @v usb               USB device
141  * @v enhanced          Hub is an enhanced hub
142  * @v data              Hub descriptor to fill in
143  * @ret rc              Return status code
144  */
145 static inline __attribute__ (( always_inline )) int
146 usb_hub_get_descriptor ( struct usb_device *usb, int enhanced,
147                          union usb_hub_descriptor *data ) {
148         unsigned int desc;
149         size_t len;
150
151         /* Determine descriptor type and length */
152         desc = ( enhanced ? USB_HUB_DESCRIPTOR_ENHANCED : USB_HUB_DESCRIPTOR );
153         len = ( enhanced ? sizeof ( data->enhanced ) : sizeof ( data->basic ) );
154
155         return usb_get_descriptor ( usb, USB_TYPE_CLASS, desc, 0, 0,
156                                     &data->header, len );
157 }
158
159 /**
160  * Get port status
161  *
162  * @v usb               USB device
163  * @v port              Port address
164  * @v status            Port status descriptor to fill in
165  * @ret rc              Return status code
166  */
167 static inline __attribute__ (( always_inline )) int
168 usb_hub_get_port_status ( struct usb_device *usb, unsigned int port,
169                           struct usb_hub_port_status *status ) {
170
171         return usb_get_status ( usb, ( USB_TYPE_CLASS | USB_HUB_RECIP_PORT ),
172                                 port, status, sizeof ( *status ) );
173 }
174
175 /**
176  * Clear port feature
177  *
178  * @v usb               USB device
179  * @v port              Port address
180  * @v feature           Feature to clear
181  * @v index             Index (when clearing a port indicator)
182  * @ret rc              Return status code
183  */
184 static inline __attribute__ (( always_inline )) int
185 usb_hub_clear_port_feature ( struct usb_device *usb, unsigned int port,
186                              unsigned int feature, unsigned int index ) {
187
188         return usb_clear_feature ( usb, ( USB_TYPE_CLASS | USB_HUB_RECIP_PORT ),
189                                    feature, ( ( index << 8 ) | port ) );
190 }
191
192 /**
193  * Set port feature
194  *
195  * @v usb               USB device
196  * @v port              Port address
197  * @v feature           Feature to clear
198  * @v index             Index (when clearing a port indicator)
199  * @ret rc              Return status code
200  */
201 static inline __attribute__ (( always_inline )) int
202 usb_hub_set_port_feature ( struct usb_device *usb, unsigned int port,
203                            unsigned int feature, unsigned int index ) {
204
205         return usb_set_feature ( usb, ( USB_TYPE_CLASS | USB_HUB_RECIP_PORT ),
206                                  feature, ( ( index << 8 ) | port ) );
207 }
208
209 /**
210  * Set hub depth
211  *
212  * @v usb               USB device
213  * @v depth             Hub depth
214  * @ret rc              Return status code
215  */
216 static inline __attribute__ (( always_inline )) int
217 usb_hub_set_hub_depth ( struct usb_device *usb, unsigned int depth ) {
218
219         return usb_control ( usb, USB_HUB_SET_HUB_DEPTH, depth, 0, NULL, 0 );
220 }
221
222 /**
223  * Clear transaction translator buffer
224  *
225  * @v usb               USB device
226  * @v device            Device address
227  * @v endpoint          Endpoint address
228  * @v attributes        Endpoint attributes
229  * @v tt_port           Transaction translator port (or 1 for single-TT hubs)
230  * @ret rc              Return status code
231  */
232 static inline __attribute__ (( always_inline )) int
233 usb_hub_clear_tt_buffer ( struct usb_device *usb, unsigned int device,
234                           unsigned int endpoint, unsigned int attributes,
235                           unsigned int tt_port ) {
236         unsigned int value;
237
238         /* Calculate value */
239         value = ( ( ( endpoint & USB_ENDPOINT_MAX ) << 0 ) | ( device << 4 ) |
240                   ( ( attributes & USB_ENDPOINT_ATTR_TYPE_MASK ) << 11 ) |
241                   ( ( endpoint & USB_ENDPOINT_IN ) << 8 ) );
242
243         return usb_control ( usb, USB_HUB_CLEAR_TT_BUFFER, value,
244                              tt_port, NULL, 0 );
245 }
246
247 /** Transaction translator port value for single-TT hubs */
248 #define USB_HUB_TT_SINGLE 1
249
250 /** A USB hub device */
251 struct usb_hub_device {
252         /** Name */
253         const char *name;
254         /** USB device */
255         struct usb_device *usb;
256         /** USB hub */
257         struct usb_hub *hub;
258         /** Features */
259         unsigned int features;
260
261         /** Interrupt endpoint */
262         struct usb_endpoint intr;
263         /** Interrupt endpoint refill process */
264         struct process refill;
265 };
266
267 /** Interrupt ring fill level
268  *
269  * This is a policy decision.
270  */
271 #define USB_HUB_INTR_FILL 4
272
273 /** Maximum time to wait for port to become enabled
274  *
275  * This is a policy decision.
276  */
277 #define USB_HUB_ENABLE_MAX_WAIT_MS 100
278
279 #endif /* _USBHUB_H */