1/**
2 * \brief This file contains all the device driver related information and
3 *        function prototypes for the USB hub class.
4 */
5
6/*
7 * Copyright (c) 2007-2013 ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15/**
16 * ==========================================================================
17 * Note: This mirrors the usb_hub.h in the USB manager, without the direct
18 * references to the transfers and devices, but with the identifiers
19 * instead
20 * ==========================================================================
21 */
22
23#ifndef LIBUSB_CLASS_HUB_H
24#define LIBUSB_CLASS_HUB_H
25
26/// the hub descriptor type value
27#define USB_DESCRIPTOR_TYPE_HUB 0x29
28
29/// the maximum depth in the USB tree
30#define USB_HUB_MAX_DEPTH   5
31
32/// the interval of the interrupt transfer
33#define USB_HUB_INTR_INTERVAL 250
34
35/// the number of transfers of the usb hub (just one)
36#define USB_HUB_NUM_TRANSFERS 1
37
38/**
39 * defines the characteristics of a hub as part of the hub descriptor
40 */
41struct usb_hub_characteristics {
42    uint8_t _reserved;          ///< reserved, should be zero
43    uint8_t port_indicator :1;  ///< are port indicators allowed
44    uint8_t tt_think_time :2;   ///< transaction translator think time
45    uint8_t protection_mode :2; ///< over current protection mode
46    uint8_t compound_device :1; ///< flag indicating if it is a compund device
47    uint8_t power_mode :2;      ///< logical power switching modes
48};
49
50/// usb hub characteristics type
51typedef struct usb_hub_characteristics usb_hub_characteristics_t;
52
53/*
54 * usb_hub_characteristics.power_mode
55 */
56
57/// usb hub logical power switching mode: treat all ports at once
58#define USB_HUB_POWER_GANGED            0
59
60/// usb hub logical power switching mode: treat all ports individual
61#define USB_HUB_POWER_INDIVIDUAL        1
62
63/// usb hub logical power switching mode: no power switching
64#define USB_HUB_POWER_NO_SWITCH         2
65
66/*
67 * usb_bub_characteristics.protection_mode
68 */
69
70/// over-current status is reported on a global (aggregated) base
71#define USB_HUB_PROTECTION_GLOBAL       0
72
73/// over-current status is reported on a per port basis
74#define USB_HUB_PROTECTION_INDIVIDUAL   1
75
76/// over current status is not reported
77#define USB_HUB_PROTECTION_NONE         2
78
79/*
80 * usb_hub_characteristics.tt_think_time
81 */
82
83/// think time is 8ms
84#define USB_HUB_TT_TIME_8       0
85
86/// think time is 16ms
87#define USB_HUB_TT_TIME_16      1
88
89/// think time is 24ms
90#define USB_HUB_TT_TIME_24      2
91
92/// think time is 32ms
93#define USB_HUB_TT_TIME_32      3
94
95//// Returns the delay from power on to power good in ms
96#define USB_HUB_POWER_ON_DELAY(hub) (hub->bPwrOn2PwrGood*2)
97
98/**
99 * ------------------------------------------------------------------------
100 * USB Hub Class Descriptor (USB Specification, Rev 2.0, Section 11.23.2.1 )
101 * ------------------------------------------------------------------------
102 * The device descriptor for USB hub class devices.
103 */
104struct usb_hub_descriptor {
105    uint8_t bDescLength;           ///< the length of the descriptor in bytes
106    uint8_t bDescriptorType;       ///< the descriptor type (0x29)
107    uint8_t bNbrPorts;             ///< the number of ports
108    struct usb_hub_characteristics wHubCharacteristics;  ///> hub characteristics
109    uint8_t bPwrOn2PwrGood;        ///< time from power on till accessible (2ms)
110    uint8_t bHubContrCurrent;      ///< max power requirements of the hub (mA)
111    uint8_t bDeviceRemovable[32];  ///< device removable bitmap (byte granularity)
112};
113
114// The maximum supported ports
115#define USB_HUB_MAX_PORTS 255
116
117// checks if the device at port is removable
118#define USB_HUB_DEVICE_REMOVABLE(desc, port) \
119        (!(((desc)->DeviceRemovable[(i)/8] >> ((i) % 8)) & 1))
120
121// size definition
122#define USB_HUB_DESCRIPTOR_MIN_SIZE 8
123
124/**
125 * ------------------------------------------------------------------------
126 * USB Hub Status (USB Specification, Rev 2.0, Table 11-19 )
127 * ------------------------------------------------------------------------
128 * The hub status struct is returned when querying the hub with the
129 * usb_hub_get_hub_status() request.
130 */
131struct usb_hub_status {
132    uint16_t _reserved :14;         ///< unused, should be zero
133    uint8_t local_power_source :1;  ///< local or external power source
134    uint8_t over_current :1;        ///< the ports are draining too much power
135    uint16_t _reserved_ :14;        ///< unused, should be zero
136    uint8_t local_power_change :1;  ///< indicates a change in local power source
137    uint8_t over_current_change :1;  ///< indicates a change in over current
138};
139
140/// usb hub status type
141typedef struct usb_hub_status usb_hub_status_t;
142
143/// check if the hub has a power supply
144#define USB_HUB_STATUS_HAS_POWERSUPPLY(st) (st->local_power_source == 0)
145
146/**
147 * ------------------------------------------------------------------------
148 * USB Hub Port Status (USB Specification, Rev 2.0, Table 11-19 )
149 * ------------------------------------------------------------------------
150 * The hub status struct is returned when querying a hub port with the
151 * usb_hub_get_port_status() request.
152 *
153 * The bit locations in the wPortStatus and wPortChange fields correspond
154 * in a one-to-one fashion where applicable.
155 *
156 * USB Specification Rev 2.0, Section 11.24.2.7.1, gives a detailed description
157 */
158struct usb_hub_port_status {
159    struct {
160        uint8_t connection :1;  ///< there is a device connected to the port
161        uint8_t enabled :1;     ///< the port is enabled
162        uint8_t suspend :1;     ///< device on that port is suspended
163        uint8_t over_current :1;       ///< a over current condition happened
164        uint8_t reset :1;       ///< is set when host wants to reset device
165        uint8_t link_state :3;  ///< USB 3.0, unused, set to zero
166        uint8_t power_state :1;  ///< local power control state
167        uint8_t is_ls :1;       ///< attached devices is a low speed device
168        uint8_t is_hs :1;       ///< attached device is a high speed device
169        uint8_t test_mode :1;   ///< port operates is in test mode
170        uint8_t indicator :1;   ///< set if indicator color is sw controlled
171        uint8_t _reserved :2;   ///< unused, set to zero
172        uint8_t device_mode :1;  ///< impl specific
173    } wPortStatus;              ///< port status flags
174    struct {
175        uint8_t connect :1;     ///< the current connect status has changed
176        uint8_t disabled :1;    ///< the port got disabled to an error
177        uint8_t resumed :1;     ///< the device resume procedure is completed
178        uint8_t over_current :1;   ///< there is a change in over_current status
179        uint8_t is_reset :1;    ///< the reset procedure on the port is complete
180        uint8_t bh_is_reset :1;
181        uint8_t linkstate :1;
182        uint8_t configerr :1;
183        uint16_t _reserved :8;  ///< unused, set to zero
184    } wPortChange;              ///< port change flags
185};
186
187/**
188 * this structure represent a port on an USB hub
189 */
190struct usb_hub_port {
191    uint8_t restarts;       ///< the number of restarts on this hub
192    uint8_t device_address;  ///< the address of the attached device
193    usb_mode_t usb_mode;    ///< the mode host or device mode
194};
195
196/// US hub port type
197typedef struct usb_hub_port usb_hub_port_t;
198
199/// the maximum number of restarts of a USB hub port
200#define USB_HUB_MAX_RESTARTS 5
201
202/**
203 * this structure defines how many bites are left in a 1ms USB time slot
204 * for full-speed isochronus schedules
205 */
206struct usb_hub_schedule {
207    uint16_t total_bytes;   ///< the total bytes of the isoc schedule
208    uint8_t frame_bytes;    ///< the bytes in this USB frame
209    uint8_t frame_slot;     ///< the slot of this USB frame
210};
211
212
213/// type definition for the different hub protocols
214typedef enum usb_hub_protocol {
215    USB_HUB_FSHUB,
216    USB_HUB_HSHUB_SINGLE_TT,
217    USB_HUB_HSHUB_MULTI_TT,
218    USB_HUB_SSHUB
219} usb_hub_protocol;
220
221#define USB_HUB_MAX_ISOC 128
222#define USB_HUB_MAX_UFRAMES 8
223
224/**
225 * Struct containing all the relevant information for an USB hub
226 * The a usb_device sets its hub field if it is a hub.
227 */
228struct usb_hub {
229    usb_hub_status_t status;
230    struct usb_hub_schedule schedule[USB_HUB_MAX_ISOC];
231    uint8_t device_address;
232    uint16_t uframe_usage[USB_HUB_MAX_UFRAMES];
233    uint16_t portpower;
234    uint8_t isoc_last;
235    uint8_t num_ports;
236    usb_hub_protocol protocol;
237    usb_hub_port_t ports[0];
238    usb_xfer_id_t xferids[USB_HUB_NUM_TRANSFERS];
239    char name[32];
240};
241
242/*
243 * device class codes
244 */
245#define USB_HUB_CLASS_CODE           0x09
246#define USB_HUB_SUBCLASS_CODE        0x00
247#define USB_HUB_PROTOCOL_FSHUB       0x00
248#define USB_HUB_PROTOCOL_HSHUBSTT    0x01
249#define USB_HUB_PROTOCOL_HSHUBMTT    0x02
250#define USB_HUB_PROTOCOL_SSHUB       0x03
251
252/*
253 * interface class code
254 */
255#define USB_HUB_IFACE_CLASS_CODE        0x09
256#define USB_HUB_IFACE_SUBCLASS_CODE     0x00
257#define USB_HUB_IFACE_PROTOCOL_FSHUB    0x00
258#define USB_HUB_IFACE_PROTOCOL_HSHUBSTT 0x00   /* Yes, same as previous */
259#define USB_HUB_IFACE_PROTOCOL_HSHUBMTT 0x01
260
261/*
262 * USB Hub Class Specific Request Codes
263 * (USB Specification, Rev 2.0, Table 11.16)
264 */
265#define USB_HUB_REQ_GET_STATUS     	 0
266#define USB_HUB_REQ_CLEAR_FEATURE  	 1
267#define USB_HUB_REQ_SET_FEATURE  	 3
268#define USB_HUB_REQ_GET_DESCRIPTOR   6
269#define USB_HUB_REQ_SET_DESCRIPTOR   7
270#define USB_HUB_REQ_CLEAR_TT_BUFFER  8
271#define USB_HUB_REQ_RESET_TT		 9
272#define USB_HUB_REQ_GET_TT_STATE  	10
273#define USB_HUB_REQ_STOP_TT			11
274
275/*
276 * USB Hub Class Specific Request Codes
277 * (USB Specification, Rev 2.0, Table 11.17)
278 */
279#define USB_HUB_FEATURE_C_HUB_LOCAL_POWER	0
280#define USB_HUB_FEATURE_C_HUB_OVER_CURRENT	1
281#define USB_HUB_FEATURE_PORT_CONNECTION		0
282#define USB_HUB_FEATURE_PORT_ENABLE			1
283#define USB_HUB_FEATURE_PORT_SUSPEND		2
284#define USB_HUB_FEATURE_PORT_OVER_CURRENT	3
285#define USB_HUB_FEATURE_PORT_RESET			4
286#define USB_HUB_FEATURE_PORT_POWER			8
287#define USB_HUB_FEATURE_PORT_LOW_SPEED		9
288#define USB_HUB_FEATURE_C_PORT_CONNECTION	16
289#define USB_HUB_FEATURE_C_PORT_ENABLE		17
290#define USB_HUB_FEATURE_C_PORT_SUSPEND		18
291#define USB_HUB_FEATURE_C_PORT_OVER_CURRENT	19
292#define USB_HUB_FEATURE_C_PORT_RESET		20
293#define USB_HUB_FEATURE_PORT_TEST			21
294#define USB_HUB_FEATURE_PORT_INDICATOR		22
295
296usb_error_t usb_hub_clear_hub_feature(uint16_t feature);
297
298usb_error_t usb_hub_clear_port_feature(uint16_t feature, uint8_t sel,
299        uint8_t port);
300
301usb_error_t usb_hub_clear_tt_buffer(uint8_t dev_addr, uint8_t ep_num,
302        uint8_t ep_type,uint8_t direction, uint16_t tt_port);
303
304usb_error_t usb_hub_get_hub_status(struct usb_hub_status *ret_status);
305
306usb_error_t usb_hub_get_port_status(uint16_t port,
307        struct usb_hub_port_status *ret_status);
308
309usb_error_t usb_hub_reset_tt(uint16_t port);
310
311usb_error_t usb_hub_set_hub_feature(uint16_t feature);
312
313usb_error_t usb_hub_set_port_feature(uint16_t feature, uint8_t selector,
314        uint8_t port);
315
316usb_error_t usb_hub_get_tt_state(uint16_t flags, uint16_t port,
317        uint16_t max_length, uint16_t ret_length, void **ret_state);
318
319usb_error_t usb_hub_stop_tt(uint16_t port);
320
321usb_error_t usb_hub_get_hub_descriptor(uint16_t max_length,
322        struct usb_hub_descriptor **ret_desc);
323
324usb_error_t usb_hub_set_hub_descriptor(uint16_t desc_length,
325        struct usb_hub_descriptor *desc);
326
327#endif
328