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