10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL
);
13 #include <ipxe/list.h>
14 #include <ipxe/process.h>
16 /** Request recipient is a port */
17 #define USB_HUB_RECIP_PORT ( 3 << 0 )
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 */
25 /** Characteristics */
26 uint16_t characteristics
;
27 /** Power-on delay (in 2ms intervals */
29 /** Controller current (in mA) */
31 } __attribute__ (( packed
));
33 /** A basic USB hub descriptor */
34 #define USB_HUB_DESCRIPTOR 41
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 */
44 /** Removable device bitmask */
46 } __attribute__ (( packed
));
48 /** An enhanced USB hub descriptor */
49 #define USB_HUB_DESCRIPTOR_ENHANCED 42
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
));
62 struct usb_hub_port_status
{
67 } __attribute__ (( packed
));
69 /** Current connect status feature */
70 #define USB_HUB_PORT_CONNECTION 0
72 /** Port enabled/disabled feature */
73 #define USB_HUB_PORT_ENABLE 1
75 /** Port reset feature */
76 #define USB_HUB_PORT_RESET 4
78 /** Port power feature */
79 #define USB_HUB_PORT_POWER 8
81 /** Low-speed device attached */
82 #define USB_HUB_PORT_LOW_SPEED 9
84 /** High-speed device attached */
85 #define USB_HUB_PORT_HIGH_SPEED 10
87 /** Connect status changed */
88 #define USB_HUB_C_PORT_CONNECTION 16
90 /** Port enable/disable changed */
91 #define USB_HUB_C_PORT_ENABLE 17
93 /** Suspend changed */
94 #define USB_HUB_C_PORT_SUSPEND 18
96 /** Over-current indicator changed */
97 #define USB_HUB_C_PORT_OVER_CURRENT 19
100 #define USB_HUB_C_PORT_RESET 20
102 /** Link state changed */
103 #define USB_HUB_C_PORT_LINK_STATE 25
105 /** Configuration error */
106 #define USB_HUB_C_PORT_CONFIG_ERROR 26
108 /** Calculate feature from change bit number */
109 #define USB_HUB_C_FEATURE( bit ) ( 16 + (bit) )
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 ) )
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 ) )
128 #define USB_HUB_SET_HUB_DEPTH \
129 ( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE | \
130 USB_REQUEST_TYPE ( 12 ) )
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 ) )
141 * @v enhanced Hub is an enhanced hub
142 * @v data Hub descriptor to fill in
143 * @ret rc Return status code
145 static inline __attribute__ (( always_inline
)) int
146 usb_hub_get_descriptor ( struct usb_device
*usb
, int enhanced
,
147 union usb_hub_descriptor
*data
) {
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
) );
155 return usb_get_descriptor ( usb
, USB_TYPE_CLASS
, desc
, 0, 0,
156 &data
->header
, len
);
163 * @v port Port address
164 * @v status Port status descriptor to fill in
165 * @ret rc Return status code
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
) {
171 return usb_get_status ( usb
, ( USB_TYPE_CLASS
| USB_HUB_RECIP_PORT
),
172 port
, status
, sizeof ( *status
) );
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
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
) {
188 return usb_clear_feature ( usb
, ( USB_TYPE_CLASS
| USB_HUB_RECIP_PORT
),
189 feature
, ( ( index
<< 8 ) | port
) );
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
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
) {
205 return usb_set_feature ( usb
, ( USB_TYPE_CLASS
| USB_HUB_RECIP_PORT
),
206 feature
, ( ( index
<< 8 ) | port
) );
214 * @ret rc Return status code
216 static inline __attribute__ (( always_inline
)) int
217 usb_hub_set_hub_depth ( struct usb_device
*usb
, unsigned int depth
) {
219 return usb_control ( usb
, USB_HUB_SET_HUB_DEPTH
, depth
, 0, NULL
, 0 );
223 * Clear transaction translator buffer
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
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
) {
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 ) );
243 return usb_control ( usb
, USB_HUB_CLEAR_TT_BUFFER
, value
,
247 /** Transaction translator port value for single-TT hubs */
248 #define USB_HUB_TT_SINGLE 1
250 /** A USB hub device */
251 struct usb_hub_device
{
255 struct usb_device
*usb
;
259 unsigned int features
;
261 /** Interrupt endpoint */
262 struct usb_endpoint intr
;
263 /** Interrupt endpoint refill process */
264 struct process refill
;
267 /** Interrupt ring fill level
269 * This is a policy decision.
271 #define USB_HUB_INTR_FILL 4
273 /** Maximum time to wait for port to become enabled
275 * This is a policy decision.
277 #define USB_HUB_ENABLE_MAX_WAIT_MS 100
279 #endif /* _USBHUB_H */