1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** USBX Component                                                        */
16 /**                                                                       */
17 /**   HUB Class                                                           */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 
23 /**************************************************************************/
24 /*                                                                        */
25 /*  COMPONENT DEFINITION                                   RELEASE        */
26 /*                                                                        */
27 /*    ux_host_class_hub.h                                 PORTABLE C      */
28 /*                                                           6.3.0        */
29 /*  AUTHOR                                                                */
30 /*                                                                        */
31 /*    Chaoqiong Xiao, Microsoft Corporation                               */
32 /*                                                                        */
33 /*  DESCRIPTION                                                           */
34 /*                                                                        */
35 /*    This file contains all the header and extern functions used by the  */
36 /*    USBX HUB class.                                                     */
37 /*                                                                        */
38 /*  RELEASE HISTORY                                                       */
39 /*                                                                        */
40 /*    DATE              NAME                      DESCRIPTION             */
41 /*                                                                        */
42 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
43 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
44 /*                                            resulting in version 6.1    */
45 /*  08-02-2021     Wen Wang                 Modified comment(s),          */
46 /*                                            added extern "C" keyword    */
47 /*                                            for compatibility with C++, */
48 /*                                            resulting in version 6.1.8  */
49 /*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
50 /*                                            added standalone support,   */
51 /*                                            resulting in version 6.1.12 */
52 /*  10-31-2023     Chaoqiong Xiao           Modified comment(s),          */
53 /*                                            optimized USB descriptors,  */
54 /*                                            resulting in version 6.3.0  */
55 /*                                                                        */
56 /**************************************************************************/
57 
58 #ifndef UX_HOST_CLASS_HUB_H
59 #define UX_HOST_CLASS_HUB_H
60 
61 /* Determine if a C++ compiler is being used.  If so, ensure that standard
62    C is used to process the API information.  */
63 
64 #ifdef   __cplusplus
65 
66 /* Yes, C++ compiler is present.  Use standard C.  */
67 extern   "C" {
68 
69 #endif
70 
71 
72 /* Define HUB Class constants.  */
73 
74 #define UX_HOST_CLASS_HUB_CLASS                                 9
75 #define UX_HOST_CLASS_HUB_PROTOCOL_FS                           0
76 #define UX_HOST_CLASS_HUB_PROTOCOL_SINGLE_TT                    1
77 #define UX_HOST_CLASS_HUB_PROTOCOL_MULTIPLE_TT                  2
78 
79 
80 /* Define HUB Class descriptor field constants.  */
81 
82 #define UX_HOST_CLASS_HUB_GANG_POWER_SWITCHING                  0x00
83 #define UX_HOST_CLASS_HUB_INDIVIDUAL_POWER_SWITCHING            0x01
84 #define UX_HOST_CLASS_HUB_NO_POWER_SWITCHING                    0x02
85 
86 #define UX_HOST_CLASS_HUB_COMPOUND_DEVICE                       0x04
87 
88 #define UX_HOST_CLASS_HUB_GLOBAL_OVERCURRENT                    0x00
89 #define UX_HOST_CLASS_HUB_INDIVIDUAL_OVERCURRENT                0x08
90 #define UX_HOST_CLASS_HUB_NO_OVERCURRENT                        0x10
91 
92 
93 /* Define HUB Class command constants.  */
94 
95 #define UX_HOST_CLASS_HUB_GET_STATUS                            0x00
96 #define UX_HOST_CLASS_HUB_CLEAR_FEATURE                         0x01
97 #define UX_HOST_CLASS_HUB_GET_STATE                             0x02
98 #define UX_HOST_CLASS_HUB_SET_FEATURE                           0x03
99 #define UX_HOST_CLASS_HUB_GET_DESCRIPTOR                        0x06
100 #define UX_HOST_CLASS_HUB_SET_DESCRIPTOR                        0x07
101 
102 
103 /* Define HUB Class set_feature command constants.  */
104 
105 #define UX_HOST_CLASS_HUB_PORT_CONNECTION                       0x00
106 #define UX_HOST_CLASS_HUB_PORT_ENABLE                           0x01
107 #define UX_HOST_CLASS_HUB_PORT_SUSPEND                          0x02
108 #define UX_HOST_CLASS_HUB_PORT_OVER_CURRENT                     0x03
109 #define UX_HOST_CLASS_HUB_PORT_RESET                            0x04
110 #define UX_HOST_CLASS_HUB_PORT_POWER                            0x08
111 #define UX_HOST_CLASS_HUB_PORT_LOW_SPEED                        0x09
112 #define UX_HOST_CLASS_HUB_C_PORT_CONNECTION                     0x10
113 #define UX_HOST_CLASS_HUB_C_PORT_ENABLE                         0x11
114 #define UX_HOST_CLASS_HUB_C_PORT_SUSPEND                        0x12
115 #define UX_HOST_CLASS_HUB_C_PORT_OVER_CURRENT                   0x13
116 #define UX_HOST_CLASS_HUB_C_PORT_RESET                          0x14
117 
118 
119 /* Define HUB Class port status constants.  */
120 
121 #define UX_HOST_CLASS_HUB_PORT_STATUS_CONNECTION                0x0001
122 #define UX_HOST_CLASS_HUB_PORT_STATUS_ENABLE                    0x0002
123 #define UX_HOST_CLASS_HUB_PORT_STATUS_SUSPEND                   0x0004
124 #define UX_HOST_CLASS_HUB_PORT_STATUS_OVER_CURRENT              0x0008
125 #define UX_HOST_CLASS_HUB_PORT_STATUS_RESET                     0x0010
126 #define UX_HOST_CLASS_HUB_PORT_STATUS_POWER                     0x0100
127 #define UX_HOST_CLASS_HUB_PORT_STATUS_LOW_SPEED                 0x0200
128 #define UX_HOST_CLASS_HUB_PORT_STATUS_HIGH_SPEED                0x0400
129 
130 
131 /* Define HUB Class port change constants.  */
132 
133 #define UX_HOST_CLASS_HUB_PORT_CHANGE_CONNECTION                0x00001u
134 #define UX_HOST_CLASS_HUB_PORT_CHANGE_ENABLE                    0x00002u
135 #define UX_HOST_CLASS_HUB_PORT_CHANGE_SUSPEND                   0x00004u
136 #define UX_HOST_CLASS_HUB_PORT_CHANGE_OVER_CURRENT              0x00008u
137 #define UX_HOST_CLASS_HUB_PORT_CHANGE_RESET                     0x00010u
138 
139 
140 /* Define HUB Class other constants.  */
141 
142 #define UX_HOST_CLASS_HUB_ENABLE_RETRY_COUNT                    3
143 #define UX_HOST_CLASS_HUB_ENABLE_RETRY_DELAY                    100
144 #define UX_HOST_CLASS_HUB_ENUMERATION_RETRY                     3
145 #define UX_HOST_CLASS_HUB_ENUMERATION_DEBOUNCE_DELAY            100
146 #define UX_HOST_CLASS_HUB_ENUMERATION_RESET_RECOVERY_DELAY      10
147 #define UX_HOST_CLASS_HUB_ENUMERATION_RETRY_DELAY               300
148 
149 
150 /* Define HUB Descriptor.  */
151 #define UX_HUB_DESCRIPTOR_ENTRIES                               8
152 #define UX_HUB_DESCRIPTOR_LENGTH                                9
153 
154 /* Define HUB Class structure.  */
155 
156 #define UX_MAX_HUB_PORTS                                        15
157 
158 
159 /* Define HUB state machine states.  */
160 
161 #define UX_HOST_CLASS_HUB_ENUM_GET_STATUS                       (UX_STATE_STEP + 0)
162 #define UX_HOST_CLASS_HUB_ENUM_POWER_CHECK                      (UX_STATE_STEP + 1)
163 #define UX_HOST_CLASS_HUB_ENUM_SET_CONFIG                       (UX_STATE_STEP + 2)
164 #define UX_HOST_CLASS_HUB_ENUM_SET_CONFIG_DONE                  (UX_STATE_STEP + 3)
165 #define UX_HOST_CLASS_HUB_ENUM_GET_HUB_DESC                     (UX_STATE_STEP + 4)
166 #define UX_HOST_CLASS_HUB_ENUM_GET_HUB_DESC_DONE                (UX_STATE_STEP + 5)
167 #define UX_HOST_CLASS_HUB_ENUM_PORT_POWER                       (UX_STATE_STEP + 6)
168 #define UX_HOST_CLASS_HUB_ENUM_PORT_POWER_DELAY                 (UX_STATE_STEP + 7)
169 #define UX_HOST_CLASS_HUB_ENUM_PORT_POWER_ON                    (UX_STATE_STEP + 8)
170 #define UX_HOST_CLASS_HUB_ENUM_PORT_NEXT                        (UX_STATE_STEP + 9)
171 #define UX_HOST_CLASS_HUB_ENUM_INTERRUPT_START                  (UX_STATE_STEP + 10)
172 #define UX_HOST_CLASS_HUB_ENUM_DONE                             (UX_STATE_STEP + 11)
173 #define UX_HOST_CLASS_HUB_ENUM_TRANS_WAIT                       (UX_STATE_STEP + 12)
174 #define UX_HOST_CLASS_HUB_ENUM_DELAY_WAIT                       (UX_STATE_STEP + 13)
175 
176 #define UX_HOST_CLASS_HUB_CHANGE_CHECK                          (UX_STATE_STEP + 0)
177 #define UX_HOST_CLASS_HUB_CHANGE_NEXT                           (UX_STATE_STEP + 1)
178 #define UX_HOST_CLASS_HUB_RESET                                 (UX_STATE_STEP + 2)
179 #define UX_HOST_CLASS_HUB_STATUS_GET                            (UX_STATE_STEP + 3)
180 #define UX_HOST_CLASS_HUB_STATUS_GET_DONE                       (UX_STATE_STEP + 4)
181 #define UX_HOST_CLASS_HUB_STATUS_PROCESS                        (UX_STATE_STEP + 5)
182 #define UX_HOST_CLASS_HUB_RESET_PROCESS                         (UX_STATE_STEP + 6)
183 #define UX_HOST_CLASS_HUB_CONNECT_PROCESS                       (UX_STATE_STEP + 7)
184 #define UX_HOST_CLASS_HUB_DISC_DISABLED                         (UX_STATE_STEP + 8)
185 #define UX_HOST_CLASS_HUB_DISC_CLEAR_1                          (UX_STATE_STEP + 9)
186 #define UX_HOST_CLASS_HUB_TRANS_WAIT                            (UX_STATE_STEP + 10)
187 #define UX_HOST_CLASS_HUB_DELAY_WAIT                            (UX_STATE_STEP + 11)
188 
189 
190 typedef struct UX_HUB_DESCRIPTOR_STRUCT
191 {
192 
193     UCHAR           bLength;
194     UCHAR           bDescriptorType;
195     UCHAR           bNbPorts;
196     UCHAR           _align_wHubCharacteristics[1];
197     USHORT          wHubCharacteristics;
198     UCHAR           bPwrOn2PwrGood;
199     UCHAR           bHubContrCurrent;
200     UCHAR           bDeviceRemovable;
201     UCHAR           bPortPwrCtrlMask;
202     UCHAR           _align_size[2];
203 } UX_HUB_DESCRIPTOR;
204 
205 
206 /* Define HUB Class instance structure.  */
207 
208 typedef struct UX_HOST_CLASS_HUB_STRUCT
209 {
210 
211     struct UX_HOST_CLASS_HUB_STRUCT
212                     *ux_host_class_hub_next_instance;
213     UX_HOST_CLASS   *ux_host_class_hub_class;
214     UX_DEVICE       *ux_host_class_hub_device;
215     UX_ENDPOINT     *ux_host_class_hub_interrupt_endpoint;
216     UX_INTERFACE    *ux_host_class_hub_interface;
217     UINT            ux_host_class_hub_instance_status;
218     UINT            ux_host_class_hub_state;
219     UINT            ux_host_class_hub_change_semaphore;
220     struct UX_HUB_DESCRIPTOR_STRUCT
221                     ux_host_class_hub_descriptor;
222     UINT            ux_host_class_hub_port_state;
223     UINT            ux_host_class_hub_port_power;
224 
225 #if defined(UX_HOST_STANDALONE)
226     UINT            ux_host_class_hub_run_status;
227     UCHAR           *ux_host_class_hub_allocated;
228     UX_TRANSFER     *ux_host_class_hub_transfer;
229 
230     USHORT          ux_host_class_hub_run_port_change;
231     USHORT          ux_host_class_hub_run_port_status;
232 
233     ULONG           ux_host_class_hub_wait_start;
234     ULONG           ux_host_class_hub_wait_ms;
235 
236     UCHAR           ux_host_class_hub_enum_state;
237     UCHAR           ux_host_class_hub_run_state;
238     UCHAR           ux_host_class_hub_next_state;
239     UCHAR           ux_host_class_hub_run_port;
240 #endif
241 } UX_HOST_CLASS_HUB;
242 
243 
244 /* Define HUB Class function prototypes.  */
245 
246 UINT    _ux_host_class_hub_activate(UX_HOST_CLASS_COMMAND *command);
247 VOID    _ux_host_class_hub_change_detect(VOID);
248 UINT    _ux_host_class_hub_change_process(UX_HOST_CLASS_HUB *hub);
249 UINT    _ux_host_class_hub_configure(UX_HOST_CLASS_HUB *hub);
250 UINT    _ux_host_class_hub_deactivate(UX_HOST_CLASS_COMMAND *command);
251 UINT    _ux_host_class_hub_descriptor_get(UX_HOST_CLASS_HUB *hub);
252 UINT    _ux_host_class_hub_entry(UX_HOST_CLASS_COMMAND *command);
253 UINT    _ux_host_class_hub_feature(UX_HOST_CLASS_HUB *hub, UINT port, UINT command, UINT function);
254 UINT    _ux_host_class_hub_hub_change_process(UX_HOST_CLASS_HUB *hub);
255 UINT    _ux_host_class_hub_interrupt_endpoint_start(UX_HOST_CLASS_HUB *hub);
256 VOID    _ux_host_class_hub_port_change_connection_process(UX_HOST_CLASS_HUB *hub, UINT port, UINT port_status);
257 VOID    _ux_host_class_hub_port_change_enable_process(UX_HOST_CLASS_HUB *hub, UINT port, UINT port_status);
258 VOID    _ux_host_class_hub_port_change_over_current_process(UX_HOST_CLASS_HUB *hub, UINT port, UINT port_status);
259 UINT    _ux_host_class_hub_port_change_process(UX_HOST_CLASS_HUB *hub, UINT port);
260 VOID    _ux_host_class_hub_port_change_reset_process(UX_HOST_CLASS_HUB *hub, UINT port, UINT port_status);
261 VOID    _ux_host_class_hub_port_change_suspend_process(UX_HOST_CLASS_HUB *hub, UINT port, UINT port_status);
262 UINT    _ux_host_class_hub_port_reset(UX_HOST_CLASS_HUB *hub, UINT port);
263 UINT    _ux_host_class_hub_ports_power(UX_HOST_CLASS_HUB *hub);
264 UINT    _ux_host_class_hub_status_get(UX_HOST_CLASS_HUB *hub, UINT port, USHORT *port_status, USHORT *port_change);
265 VOID    _ux_host_class_hub_transfer_request_completed(UX_TRANSFER *transfer_request);
266 
267 UINT    _ux_host_class_hub_tasks_run(UX_HOST_CLASS *hub_class);
268 
269 /* Determine if a C++ compiler is being used.  If so, complete the standard
270    C conditional started above.  */
271 #ifdef __cplusplus
272 }
273 #endif
274 
275 #endif
276 
277